E5 – Tomás Fuentes

Presentación de ideas para el proyecto  final del curso.

MediaLab – Encargo 5 from tafuentesc

Examen Final – Green Pet

La idea sobre Green Pet surgió a partir de mi gusto por la fotografía de paisajes y el gusto de mis padres por la jardinería. Ocasionalmente suelo ayudarles a plantar árboles y flores en la casa, por lo que siempre he estado ligado a éstas. Adicionalmente, mi pasión por los videojuegos me hizo recordar los tiempos de las mascotas virtuales, lo que terminó convirtiéndose en el proyecto final: convertir a una planta en una mascota virtual. El concepto tras el proyecto era bastante simple: Crear una batería de sensores que, unidos a la planta, permitieran registrar su estado e informarle al usuario sobre éste de forma intuitiva a través de un avatar virtual, el cual fuera desplegado en el computador. Aunque en un principio se consideró la idea de utilizar una pantalla LCD para hacer al proyecto autocontenido, la falta de disponibilidad de ésta y el escaso tiempo llevó a descartar la idea. Interfaz_1(3)_2 Para la primera presentación de avance, se logró implementar 3 sensores – temperatura,  luz y tacto – sobre la base de una RedBoard con el objetivo de obtener feedback del entorno. Para desplegar el contenido se implementó una interfaz minimalista y dura en processing, la cual sólo mostraba las mediciones de los sensores. Esto se hizo para mostrar que la conexión serial se encontraba funcionando perfectamente. Durante esta revisión se descartó el uso del sensor de tacto y se sugirió adquirir un sensor de humedad ambiental.   iteracion1

Primeras pruebas con los sensores y la intefaz básica

Durante la siguiente semana el enfoque estuvo en crear una interfaz más amigable para la aplicación. En este punto mi falta de práctica en dibujos complejos con processing me pasó la cuenta, por lo que el avance fue más lento de lo esperado. De todas formas se cerró la idea base de la interfaz y se adquirió la planta para la demostración. Lamentablemente el sensor de humedad se encontraba agotado, por lo que no fue posible implementarlo. InterfazVisual_2.0

Desarrollo de la interfaz visual más atractiva

Iteracion3Finalmente, para la presentación final se adquirió un sensor de humedad de suelo, lo que permitió agregar esta funcionalidad al proyecto. Una vez implementados todos los sensores, se modificó la comunicación serial para transmitir estados en vez de mediciones, de forma de que la aplicación en processing supiera fácilmente qué mostrar al usuario. Adicionalmente, y dado que era incómodo llevar el circuito en una caja, se optó por construir una base para la aplicación, la cual contuviera el circuito del proyecto y la planta en cuestión. Durante su construcción se modificó la distribución de las componentes y se agregaron leds para dar feedback al usuario sin necesidad de mirar el avatar en el computador, de forma de mejorar la estética y usabilidad.

IteracionFinalVersión Final del circuito

A continuación se adjunta la presentación final del examen:

Presentación Green Pet – Media Lab from tafuentesc

 

Demostración del funcionamiento de la aplicación:

Demostración Green Pet – MediaLab from Media LabUC on Vimeo.

El código utilizado para construir la aplicación:

Arduino:

Processing:

Examen Final Parrague y Vásquez

IMG_0566

Bicicletas en la Ciudad_Final Parrague y Vásquez from MediaLabUC

Bicicletas en la Ciudad_Final Parrague y Vásquez from Media LabUC on Vimeo.

CódigoArduino:  



int sensor = A0; 

int LEDpin = 11;      

int fsrReading;


const int buttonPin = 2;     
const int ledPin =  13;      

int buttonState = 0;         


void setup(void) {

  Serial.begin(9600);  

  pinMode(LEDpin, OUTPUT);
  pinMode(ledPin, OUTPUT);      
  pinMode(buttonPin, INPUT); 

}

 

void loop(void) {
  
  fsrReading = analogRead(sensor);

  Serial.print("Analog reading = ");

  Serial.println(fsrReading);


if(analogRead(sensor)<24){
  digitalWrite(LEDpin, HIGH);   // turn the LED on (HIGH is the voltage level)
}
if(analogRead(sensor)>25)
  digitalWrite(LEDpin, LOW);    // turn the LED off by making the voltage LOW
  
  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH)  
    // turn LED on:    
{    digitalWrite(ledPin, HIGH);
  delay(600); 
    // turn LED off:
    digitalWrite(ledPin, LOW); 
 delay(600);
}    
}

Examen-Fotografía en alta velocidad

Viva la pared, main projector y las piramides

Creado por Rodolfo Otero y Cristián Wood

Nuestro proyecto comenzó con una idea bastante diferente al resultado final, en gran parte por nuestra falta de conocimiento en el área, en resumen proponíamos algo demasiado aspiracional y complejo para desarrollar dentro del período de tiempo y  con nuestros pocos conocimientos.

En pocas palabras, queríamos darle vida a la pared, y en consecuencia generar un  nuevo ambiente  que sugiriera a los participantes de la instalación replantearse el concepto de lugar y estar en él; cómo éste se habita.

chika

+

rain

Para conseguirlo queríamos usar mapping, para proyectar algún tipo de diseño generativo sobre las paredes de una habitación específica, creando un nuevo lugar, además la idea era el diseño se creara a partir de estímulos que los participantes eran capaces de alterar, como el sonido y la luz. En otras palabras, las paredes estarían animadas con diseños que cambian constantemente producto de alteraciones físicas, como luz o sonido, en el lugar, o sea que si hay mucho ruido en la sala el diseño sería diferente al que habría si la sala estuviese en silencio.

Para lograr una instalación como esta era necesario investigar, averiguar, aprender y generar contenidos para llegar a buen puerto. Las imágenes que vemos arriba son referentes que reflejan nuestro propósito, por un lado se ven unos cubos siendo mapeados, donde un proyector los “pinta” y a través de la interfaz de mad mapper que vemos en la pantalla del computador se ajustan las imágenes proyectadas a las superficies. Por otro lado, la otra imagen muestra una instalación donde las personas podían caminar por la lluvia sin que se mojen…cómo?! Todas las pequeñas mangueritas que generan esta lluvia artificial estaban conectadas a sensores que detectaban la silueta de la personas y suprimían el flujo de agua en esa zona.

Sin más que ganas de empezar comenzamos a investigar cómo conseguir lo que nos proponíamos, y mientras más información encontrábamos, más nos confundíamos. Lo complicado era que no sabíamos nada del proceso de mapeo y sus programas, además lo poco que manejamos de programación nos limitaba en el proceso de encontrar y experimentar cómo transformar el sonido en una variable que afecte el estado de un dibujo, y lo modifique de alguna forma.

Con el tiempo encima optamos por simplificar nuestra idea, para lograr una bonita entrega en vez de unos pocos códigos mal resueltos, por lo que cortamos el trabajo con Processing y Arduino para enfocarnos en lo que desde un principio nos atrajo a la nueva área mediática, el mapping.

Captura de pantalla 2013-11-29 a la(s) 9.11.03

Con programas simples como Mad Mapper, el proceso se ha vuelto accesible para toda persona con un computador regular que desee incursionar en el tema, y lo bueno con esto es que se está avanzando con un paso sumamente experimental, por lo que la creatividad es la que va marcando el paso, y las posibilidades se han vuelto infinitas.

Encantados con el programa empezamos a aprender en base a blogs, tutoriales y vídeos con todo tipo de contenido relacionado al atractivo mapping, en la consigna para descubrir el potencial de estas nuevas herramientas. Así nos topamos con la relación que tiene Map Mapper y Quartz Composer, el último es un lenguaje de programación visual en base a nodos. Este programa es parte del ambiente de Xcode, donde se usa para procesar y renderizar datos gráficos, lo que nos permite convertir casi cualquier dato que el computador procesa en información visual, la que luego se puede incrustar <>  en Mad Maper, donde podemos proyectar el contenido.

Ahora sólo faltaba conseguir qué datos convertir en imágenes, y ahondando en lo anterior descargamos Abletone Live, donde podemos generar notas musicales en MIDI, las que pueden subir a un audio bus, por así decirlo, y recorrer todo el computador, es como si las notas que Abletone emite fueran escuchadas por todas las aplicaciones del computador que sean capaces de hacerlo, o hayan sido habilitadas para ello, como puede serlo Quartz Composer.

Captura de pantalla 2013-11-29 a la(s) 9.31.54Acto seguido enlazamos las notas de la melodía que hicimos en Abletone a un Sprite en Quartz Composer que se encarga de recibir la nota y transformarla en luz dentro de un plano de unos 500 x 400 pixeles, si esto funcionaba correctamente, luego podríamos enmascarar y teñir esas luces en Mad Mapper, para que así las notas pasen a ser luces de colores sobre una superficie. De esta manera podríamos reproducir cualquier canción que hiciéramos en MIDI, las que serían proyectadas sobre lo que quisiéramos, consiguiendo aportar algo diferente y audaz a la monotonía del espacio.

Captura de pantalla 2013-11-29 a la(s) 9.41.34

Sin embargo quisimos ir un paso más allá, y dejando un poco de lado la idea de una animación orgánica que aportara al lugar decidimos hacer un lugar participativo. Cuando ya vimos que era efectivo hacer que la música se transformara en luz pensamos…¿Qué pasa si en vez de reproducir canciones, conectamos un teclado MIDI al computador y con él tocamos música? Cada tecla estaría sincronizada con una superficie específica, y la reproducción común de una melodía inmediatamente obtendría una segunda lectura, visual y tremendamente inmersiva.
Captura de pantalla 2013-11-29 a la(s) 9.42.22

Conectamos un teclado y lo configuramos con Abletone, que ya estaba programado para emitir los sonidos MIDI al resto de la interfaz, y funcionó! En la última imagen donde se ve el Quartz Composer también se observa la ventana negra y un rectángulo blanco, que es la traducción de la nota en un espacio de luz sobre el plano, y atrás al otro lado se ve la interfaz de Mad Mapper, ya mapeada la figura y transformando la nota en un triángulo amarillo.

Construimos una maqueta para probar todo en una escala real, de esta manera si todo sale como lo pensamos, no tendíamos ningún problema para el examen y para volver a hacer este proyecto en 8 mil lugares diferentes y con 8 mil variables nuevas.Captura de pantalla 2013-11-29 a la(s) 9.42.38Lo mejor de todo es que funcionó! Y no tuvimos ni una sola complicación, fue difícil y fue aprender algo nuevo, pero fue de una manera muy efectiva, fluida y agradablemente libre de errores. Como les decíamos, este es un proyecto con un potencial infinito, por eso en parte también decidimos hacer un diamante de pirámides, es un módulo, que se puede replicar todo lo que se desee en una superficie y generar el mismo efecto en una escala mucho mayor, por lo que las reacciones de los participantes  en realidad pueden llegar a ser incluso más grandes que con ésta humilde maqueta.

En fin, si bien el potencial que tiene no es muy relevante más que para nuestro goce de un trabajo bien hecho, lo positivo es que funciona, es fácil y todos pueden hacerlo, aquí está toda la información para empezar a hacerlo ustedes mismos, pero si desean nosotros no tenemos ningún problema en ayudarles, porque lo aprendimos y nos encanta, así que son libres de contactarnos cuando quieran!

¡Saludos!

Main Projector y las piramides from Cristián Wood Benjamín Schöbi on Vimeo.

Blog patiperros

Blog PROCESSEANDO

Documentación del proyecto Patiperros

Engrama – Presentación Final

Engrama partió como un cuestionamiento al modo en el que se aprende en los colegios y las universidades de Chile. El tema de la educación ha estado en boca de todos desde la Revolución Pingüina de 2006, y tomó una relevancia aún más especial con el Movimiento Estudiantil de 2011. En ambas manifestaciones ciudadanas, los temas centrales fueron la desigualdad en el acceso, y la calidad de la educación recibida.

Tomando la temática sobre la calidad de la educación, queríamos mostrar como han cambiado los medios -gracias al internet, redes sociales, smartphones-, y cuan poco ha cambiado la forma de hacer clases: Un profesor se para adelante de la sala, habla y escribe en la pizarra, y luego da ejercicios preestablecidos, suponiendo que ésto es más interesante para sus alumnos que entrar a Facebook para ver fotos de sus amigos. En esta línea nos llamó muchísimo la atención la aplicación Verso, la cual se basa en la metodología Flip Your Thinking, la cual propone que sean los alumnos quienes generen las preguntas para luego ser respondidas en clases.

El medio que nos impusimos para generar nuestro proyecto fue el utilizar los conocimientos adquiridos a lo largo del semestre tanto en Processing como en Arduino. Nos llamó particularmente la atención este último, así que nos enfocamos fuertemente en aprender sus capacidades para generar un producto útil.

Además no quisimos quedarnos sólo en lo técnico. De ningún modo nos conformamos con aprender a programar, soldar y a montar circuitos. Pretendimos darle a nuestro proyecto un sentido final más acabado: generar un aprendizaje básico de programación a niños que nunca hubieran tenido un acercamiento a esta temática.


IMG_1206Nuestro primer prototipo constaba de una Arduino ReadBoard, conectada a una pequeña breadboard  montada con dos hileras de LED’s, una de color rojo, y otra amarilla. Además había un sensor de luz y un botín. Cuando el umbral de luz medido por el sensor pasaba de cierta cifra -por ejemplo al acercarle una linterna-, al apretar el botón se encendía la fila de LED’s rojos. Por otra parte, si no se acercaba ninguna luz, se encendía la amarilla. Para ocultar todos los circuitos los tapamos con una caja de carton roja. Cortamos por lado un orificio para el sensor de luz, otro para presionar el botón, y otro para el cable USB al computador. En la parte superior colocamos una pequeña ventana tapada con un papel traslúcido. Entonces, esta ventana se ponía de color rojo si había luz, o amarilla si no.

 

Luego de mostar este prototipo a las Profesoras, nos hicieron ver que la caja que tabapa todo el circuito no respondía con nuestra crítica a las clases a la antigua; más aún, escondíamos toda la magia a los niños. La idea era transparentar y hacer gráfica la idea de que si había luz, se encendían las luces de color rojo, mientras que si no había luz, se encendían las de color amarillo.

 

 

IMG_1205En nuestra segunda versión mantuvimos los el mismo el mismo circuito, pero en vez de la caja de cartón utilizamos un papel de transparencias impreso (en la foto colocamos un papel blando detrás para que se pudiera ver correctamente). Aquí adjuntamos el PDF que imprimimos sobre la transparencia: Caja Transparente Engrama V1.

Mostramos en la clase siguiente nuestro nuevo prototipo, y el feedback que recibimos nos instó a hacer más grande la sección de Engrama, y a dejar que el profesor encargado explicase la sección de Arduino, dándole mayor énfasis en el gráfico didáctico que explica como se utiliza nuestro dispositivo. Además, las profesoras nos plantearon el desafío de soldar nuestro circuito en una tarjeta perforada, para darle un look más acabado para el exámen.

 

Finalmente generamos el siguiente sticker para nuestra caja mágica:Captura de pantalla 2013-11-28 a la(s) 19.21.47


Y tras un buen rato soldando y cortando acrílicos logramos generar la versión que presentamos en el exámen:

Captura de pantalla 2013-11-28 a la(s) 23.12.55 Captura de pantalla 2013-11-28 a la(s) 23.13.04 Captura de pantalla 2013-11-28 a la(s) 23.13.25

 

La presentación usada en el exámen: 

Proyecto Engrama – Presentación Exámen Medialab from vichoiglesias

 

El Código que utilizamos para programar el Arduino:

Ubicuo /Della Maggiora – Melo – Reyes

 Ubicuo

Della Maggiora – Melo – Reyes

 a

  • Presentación

Presentación Ubicuo from Francisco Reyes
  • Maqueta App

App from Francisco Reyes
  • Video App

  • Video Proceso

 

  • Luz – ARDUINO

 

 

  • Luz – PROCESSING

 

 

  • Volumen- ARDUINO

 

 

  • Volumen- PROCESSING

 

 

  • Work in progress – LASER

 

 

 

  • Dropbox (Backup archivos originales + renders)

https://www.dropbox.com/sh/0482jhz7pomhf0j/DUMeb6NuHC

 

 

Hackeo de Robot para dibujo – Vicente Zabala – Pablo Gaete

En la antigüedad Miguel Angel esculpió El David con un martillo y un cincel, sin la posiblidad de deshacer errores. En la actualidad, las máquinas han inculcado la idea del “Ctrl+Z”, con lo cual se ha perdido el romanticismo de que cada acción tiene consecuencias y no se puede escapar de ellas.
Por otro lado, las máquinas permiten nuevas habilidades como replicas perfectas y escalamientos que serían realmente complejos sin la ayuda de estas. Estas habilidades nos dan la posibilidad de explorar con técnicas y herramientas, a velocidades que nunca pensamos pues una nueva técnica solo implica el cambio del “elemento actuador”.
Es en esta linea que hemos hackeado un “robot” cartesiano (máquina que se mueve, como su nombre lo indica, siguiendo coordenadas cartesianas) y hemos dibujado con él, replicando el mismo dibujo con 5 técnicas y configuraciones distintas. Estas fueron 3 plumones de punta flexible de colores cyan, amarillo y magenta, dispuestos en linea con una separación de 13mm, también con 3 plumones para pizarra acrílica en colores azul, rojo y negro dispuesto en linea con separación de 16mm, además con 3 lapices de colores en azul, rojo y negro dispuests en linea con una separación de 12mm, también con y crayones verde azul y naranjo dispuestos de la misma forma separados por 17mm y finalmente dibujando con una goma de borrar sobre un papel coloreado con grafito.
Con esto hemos generado una serie artística que se puede apreciar en la imagen.
Nuestro código fue generado en c# con la ayuda del software “Visal Studio 2012”, usando una programación orientada a objetos compuesto por 6 clases donde el main es bastante resumido. Se adjuntan las secciones importantes de este código.
También se adjunta un código que muestra el formato que recibe el robot cartesiano, la presentación con videos incluidos y un video aparte que muestra el proceso de dibujo de un modo más macro.
serie rana

Video de el proceso de dibujo:

 

Presentación Final:

Hackeo de-robot-para-dibujo from MediaLabUC

Codigo en C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;

namespace Festo
{
    /// <summary>
    /// Class that represents a motor.
    /// </summary>
    internal class Motor
    {
        private string serialPortName;      // Name of the serial port (COMx)
        private char axis;                  // The axis that the motor moves ('x' or 'y')
        private SerialPort serialPort;      // Serial port

        /// <summary>
        /// Event raised when a message is sent to the controller.
        /// It contains the sent string.
        /// </summary>
        public event Action<string> OnMessageSent;
        /// <summary>
        /// Event raised when a message is received from the controller.
        /// It contains the received string.
        /// </summary>
        public event Action<string> OnMessageReceived;

        /// <summary>
        /// Class constructor.
        /// </summary>
        /// <param name="name">Serial port name (COMx)</param>
        /// <param name="ax">Axis to control ('x' or 'y').</param>
        public Motor(string name, char ax)
        {
            serialPortName = name;
            axis = ax;
        }

        #region Serial port handling

        /// <summary>
        /// Initialize serial port.
        /// </summary>
        /// <returns>Configured baud rate of the controller.</returns>
        public int InitSerialPort()
        {
            serialPort = new SerialPort(serialPortName);    // Creates a new instance of a serial port
            serialPort.NewLine = "\r";                      // Controller works with this line feed
            return SearchCorrectBaudRate();                 // Search in which baud rate the controller is configured
        }
        /// <summary>
        /// Search in which baud rate the controller is configured.
        /// </summary>
        /// <returns>Configured baud rate of the controller.</returns>
        public int SearchCorrectBaudRate()
        {
            foreach (int bps in Constants.AdmitedBaudRates)
            {
                try
                {
                    serialPort.Close();
                    serialPort.BaudRate = bps;
                    serialPort.Open();
                    serialPort.ReadTimeout = 100;
                    string s = Send(CommandParser.DisableController(), true);
                    if (s != null)
                    {
                        serialPort.ReadTimeout = -1;
                        return bps;
                    }
                }
                catch { }
            }
            serialPort.BaudRate = 1;
            return -1;
        }
        /// <summary>
        /// Tries to change the communication baud rate.
        /// </summary>
        /// <param name="bps">Desired baud rate in BPS.</param>
        /// <returns>Configured baud rate of the controller.</returns>
        public int ChangeBaudRate(int bps)
        {
            int bps_prev = serialPort.BaudRate;
            try
            {
                string response = Send(CommandParser.SetBaudRate(bps), true);
                if (response.ToLower().Contains("ok"))
                {
                    serialPort.BaudRate = bps;
                    return bps;
                }
            }
            catch { }
            serialPort.BaudRate = bps_prev;
            return bps_prev > 1 ? bps_prev : -1;
        }

        /// <summary>
        /// Disable controller and close serial port.
        /// </summary>
        public void ClosePort()
        {
            try
            {
                Send(CommandParser.DisableController(), false);
                serialPort.Close();
            }
            catch
            { }
        }
        /// <summary>
        /// Close and reopen serial port, then reset the motor controller.
        /// </summary>
        public void ResetCommunication()
        {
            try
            {
                serialPort.Close();
                serialPort.Open();
            }
            catch { }
            ResetMotor();
        }

        /// <summary>
        /// Send command to the controller.
        /// </summary>
        /// <param name="s">Commnad string.</param>
        /// <param name="waitResponse">Defines whether to wait for a controller's response or not.</param>
        /// <returns></returns>
        private string Send(string s, bool waitResponse)
        {
            OnMessageSent("" + axis + "> " + s);
            try
            {
                serialPort.DiscardInBuffer();
                serialPort.DiscardOutBuffer();

                serialPort.WriteLine(s);
                if (waitResponse)
                    return Receive();
            }
            catch { }
            return null;
        }
        /// <summary>
        /// Receive a message from the controller.
        /// </summary>
        /// <returns></returns>
        private string Receive()
        {
            try
            {
                string s = serialPort.ReadLine();
                OnMessageReceived("" + axis + "> " + s);
                return s;
            }
            catch
            {
                return null;
            }
        }

        #endregion

        #region Configuration

        /// <summary>
        /// Disable motor controller.
        /// </summary>
        public void DisableMotor()
        {
            Send(CommandParser.DisableController(), true);
        }
        /// <summary>
        /// Disable and re-enable motor controller.
        /// </summary>
        public void ResetMotor()
        {
            Send(CommandParser.DisableController(), true);
            Send(CommandParser.EnableController(), true);
        }
        /// <summary>
        /// Set the positioning mode of the controller.
        /// </summary>
        /// <param name="m"></param>
        public void SetPositioningMode(Constants.PositioningModes m)
        {
            Send(CommandParser.SetPositioningMode(03, m), true);
        }
        /// <summary>
        /// Set the maximum operating speed of the motor.
        /// </summary>
        /// <param name="vRPM">Speed in RPM.</param>
        public void SetMaxSpeed(int vRPM)
        {
            Send(CommandParser.SetVmaxRpm(03, vRPM), true);
        }
        /// <summary>
        /// Set the final speed of the movement.
        /// </summary>
        /// <param name="RPMvel">Speed in RPM.</param>
        public void DefineFinalSpeed(int RPMvel)
        {
            Send(CommandParser.SetVendRpm(03, RPMvel), true);
        }
        /// <summary>
        /// Set the destination position of the movement.
        /// </summary>
        /// <param name="pos">Position in millimetres.</param>
        public void SetDestinationPosition(double pos)
        {
            Send(CommandParser.SetDestinationPosition(03, pos, axis), true);
        }
        /// <summary>
        /// Starts positioning.
        /// </summary>
        public void StartPositioning(bool waitResponse)
        {
            Send(CommandParser.StartPositioning(03), waitResponse);
        }

        // Default
        /// <summary>
        /// Sets standard configuration of the motor controller.
        /// </summary>
        /// <param name="setStandardVmax">Defines whether to configure maximum speed or not.</param>
        public void SetDefaultConfiguration(bool setStandardVmax)
        {
            // Sets positioning mode on absolute with previous movement interruption.
            Send(CommandParser.SetPositioningMode(03, Constants.PositioningModes.AbsoluteAndInterrupt), true);

            // Sets standard acceleration times.
            Send(CommandParser.SetAccelerationTime(3, Constants.StandardAccelerationTimeMs), true);
            Send(CommandParser.SetAcelerationSmoothPartTime(3, Constants.StandardAccelerationTimeMs), true);
            Send(CommandParser.SetBrakingTime(3, Constants.StandardAccelerationTimeMs), true);
            Send(CommandParser.SetBrakingSmoothPartTime(3, Constants.StandardAccelerationTimeMs), true);

            // If desired, sets standard maximum speed.
            if (setStandardVmax)
                Send(CommandParser.SetVmaxRpm(03, axis == 'x' ? Constants.XStandardSpeedRPM : Constants.YStandardSpeedRPM), true);

            // Sets final speed in 0.
            Send(CommandParser.SetVendRpm(03, 0), true);

            // Enables controller.
            Send(CommandParser.EnableController(), true);
        }
        /// <summary>
        /// Sets standard maximum speed.
        /// </summary>
        public void SetDefaultSpeed()
        {
            Send(CommandParser.SetVmaxRpm(03, axis == 'x' ? Constants.XStandardSpeedRPM : Constants.YStandardSpeedRPM), true);
        }

        #endregion

        #region Movements

        /// <summary>
        /// Go to reference point (origin).
        /// </summary>
        public void MoveToReference()
        {
            Send(CommandParser.GoToReference(), true);
        }
        /// <summary>
        /// Move to specified position.
        /// </summary>
        /// <param name="positionMM">Position in millimetres.</param>
        public void MoveToPosition(double positionMM)
        {
            Send(CommandParser.SetDestinationPosition(03, positionMM, axis), true);
            Send(CommandParser.StartPositioning(03), true);
        }
        /// <summary>
        /// Move to the center of the axis.
        /// </summary>
        public void MoveToCenter()
        {
            if (axis == 'x')
                MoveToPosition(Constants.XAxisLengthMM / 2);
            else
                MoveToPosition(Constants.YAxisLengthMM / 2);
        }
        /// <summary>
        /// Move to the edge of the axis.
        /// </summary>
        /// <param name="positiveDirection">Defines what edge to go.</param>
        public void MoveToLimit(bool positiveDirection)
        {
            if (axis == 'x')
                MoveToPosition(positiveDirection ? Constants.XAxisLengthMM : 0);
            else
                MoveToPosition(positiveDirection ? Constants.YAxisLengthMM : 0);
        }
        /// <summary>
        /// Move relative to actual position.
        /// </summary>
        /// <param name="distanceMM">Distance to move in millimetres (positive or negative).</param>
        public void MoveRelative(double distanceMM)
        {
            // Set relative positioning mode.
            Send(CommandParser.SetPositioningMode(03, Constants.PositioningModes.RelativeAndInterrupt), true);

            // Positioning.
            MoveToPosition(distanceMM);

            // Go back to absolute positioning mode.
            Send(CommandParser.SetPositioningMode(03, Constants.PositioningModes.AbsoluteAndInterrupt), true);
        }
        /// <summary>
        /// Stop motor movement.
        /// </summary>
        public void Stop()
        {
            MoveRelative(0);
        }

        #endregion

        #region Parameters reading

        /// <summary>
        /// Read actual position of the actuator.
        /// </summary>
        /// <returns>String containing the position.
        /// Format: "xxxx:CPXIST:XXXXXXXX". Where XXXXXXXX represents the position in hexadecimal form.</returns>
        public string ReadActualPosition()
        {
            return Send(CommandParser.ReadActualPosition(), true);
        }

        /// <summary>
        /// Just wait until a message is received from the motor controller.
        /// </summary>
        /// <returns>Message received.</returns>
        public string WaitForReceive()
        {
            return Receive();
        }

        #endregion
    }
}

Ejemplo de código leído por el Robot Cartesiano

360;320;cu
360;120;cd
160;120;cd
160;320;cd
360;320;cd
237.459227467811;243.002680965147;cu
221.390557939914;243.002680965147;cd
220.497854077253;229.436997319035;cd
246.386266094421;228.257372654155;cd
247.278969957082;209.383378016086;cu
247.278969957082;234.155495978552;cd
267.811158798283;234.745308310992;cd
267.364806866953;195.227882037534;cd
246.832618025751;196.407506702413;cd
246.832618025751;212.332439678284;cd
245.93991416309;199.356568364611;cu
235.227467811159;196.407506702413;cd
234.334763948498;227.077747989276;cd
240.583690987124;210.563002680965;cu
237.905579399142;211.742627345845;cd
237.905579399142;217.050938337802;cd
241.922746781116;218.230563002681;cd
240.137339055794;211.152815013405;cd
258.884120171674;211.152815013405;cu
258.437768240343;219.41018766756;cd
262.901287553648;218.820375335121;cd
262.901287553648;209.383378016086;cd
258.884120171674;211.742627345845;cd
227.639484978541;242.412868632708;cu
217.37339055794;257.747989276139;cd
218.266094420601;263.646112600536;cd
248.618025751073;266.595174262735;cd
266.918454935622;266.005361930295;cd
275.845493562232;256.56836461126;cd
237.459227467811;243.002680965147;cu
263.347639484979;241.823056300268;cd
275.399141630901;237.69436997319;cd
287.004291845494;251.260053619303;cd
284.772532188841;274.85254691689;cd
270.935622317597;283.699731903485;cd
246.832618025751;283.699731903485;cd
234.334763948498;273.083109919571;cd
232.103004291845;265.415549597855;cd
234.334763948498;196.407506702413;cu
230.763948497854;191.689008042895;cd
236.56652360515;181.662198391421;cd
241.922746781116;144.504021447721;cd
256.206008583691;130.938337801609;cd
289.682403433476;127.98927613941;cd
312;151.581769436997;cd
312.44635193133;179.892761394102;cd
305.751072961373;245.361930294906;cd
311.55364806867;262.466487935657;cd
289.236051502146;220.58981233244;cu
293.699570815451;204.075067024129;cd
304.412017167382;208.203753351206;cd
308.429184549356;221.179624664879;cd
300.841201716738;239.463806970509;cd
290.575107296137;235.335120643432;cd
300.841201716738;224.128686327078;cu
296.377682403433;230.026809651475;cd
293.699570815451;224.718498659517;cd
297.716738197425;212.922252010724;cd
251.742489270386;133.297587131367;cu
254.420600858369;123.860589812332;cd
276.291845493562;122.680965147453;cd
288.789699570815;142.144772117962;cd
288.343347639485;152.171581769437;cd
272.274678111588;129.16890080429;cu
279.416309012876;123.270777479893;cd
301.287553648069;129.16890080429;cd
307.982832618026;139.785522788204;cd
302.18025751073;150.991957104558;cd
288.789699570815;201.71581769437;cu
295.931330472103;168.096514745308;cd
301.733905579399;190.509383378016;cd
318.695278969957;172.225201072386;cd
314.678111587983;210.563002680965;cd
307.090128755365;248.310991957105;cu
319.587982832618;254.209115281501;cd
277.630901287554;287.238605898123;cd
295.038626609442;306.112600536193;cd
321.81974248927;268.364611260054;cd
318.695278969957;253.619302949062;cd
277.630901287554;287.828418230563;cu
269.596566523605;300.214477211796;cd
262.901287553648;285.469168900804;cd
256.652360515021;296.085790884719;cd
266.025751072961;291.957104557641;cd
255.759656652361;294.906166219839;cu
257.545064377682;283.699731903485;cd
263.347639484979;285.469168900804;cu
268.257510729614;283.699731903485;cd
269.150214592275;296.085790884719;cu
269.596566523605;283.699731903485;cd

E04 Della Maggiora

E04 Della Maggiora

Untitled-6

https://gist.github.com/anonymous/7610865