Tutorial - Comunicación serial (Décima parte - Envío de datos multivariable y multifunción con botón único)

Para el siguiente experimento, enviaremos un dato que varía entre 0 a 100 que corresponde de 0 a 100%, que es análogo de los 0 a 255 bits que maneja la salida PWM a través de la función "AnalogWrite()", y que se distingue en la intensidad de luz del led, siendo 0% un led apagado y 100% un led totalmente prendido.

Los únicos pines que pueden usar la función de salida PWM en el caso del Arduino UNO de manera nativa son:
# 11
# 10
# 9
# 6
# 5
# 3

Esta data mencionada, será enviada usando una GUI elaborada en Processing usando la librería ControlP5, el dato será ingresado en cuato campos de texto y el envío es por medio de un botón único por cada dos campos. Con esto, simularemos lo que haríamos en caso de querer enviar datos a dos procesos diferentes que actúan en paralelo.

La conexión es la siguiente:
# PIN D11 : Arduino UNO => Resistencia => LED 1 : Ánodo
# PIN D10 : Arduino UNO => Resistencia => LED 2 : Ánodo
# PIN D9 : Arduino UNO => Resistencia => LED 3 : Ánodo
# PIN D6 : Arduino UNO => Resistencia => LED 4 : Ánodo
# GND : Arduino UNO => LED 1, 2, 3 y 4: Cátodo


El programa usado para el Arduino es el que se muestra:
/* PROGRAMA DE PRUEBA DE COMUNICACION SERIAL
   CONEXION:
             GRUPO 1
             Arduino (D11) : Catodo del led 1 
             Arduino (D10) : Catodo del led 2
             Arduino (GND): Anodo del led 1, 2

             GRUPO 2
             Arduino (D9) : Catodo del led 3 
             Arduino (D6) : Catodo del led 4
             Arduino (GND): Anodo del led 3, 4
             
   El siguiente programa nos ayuda a enviar una trama ingresada por puerto serial para ser leida por el 
   Arduino y ser convertida en el valor del PWM de 0 a 100% (0 - 255 bits)

   Formato del dato: Aporcentaje_1,porcentaje_2 como AXXX,YYY
                     Bporcentaje_3,porcentaje_4 como BXXX,YYY

   NOTA: Los pienes que poseen salida PWM son 3, 5, 6, 9, 10 y 11

   Autor: Renato Hurtado
   http://beetlecraft.blogspot.pe/
    
   El siguiente programa es de uso publico, cualquier modificacion o mal uso del mismo que pudiera 
   ocasionar el mal funcionamiento de la plataforma de uso de la misma no es responsabilidad del autor
*/

const int led_1 = 11, led_2 = 10, led_3 = 10, led_4 = 9; // Variable asignada al pin led 1, 2, 3 y 4
String data; // Variable asignada al dato obtenido

void setup() {
  pinMode(led_1, OUTPUT); // Configuracion del pin led 1 como salida
  pinMode(led_2, OUTPUT); // Configuracion del pin led 2 como salida
  pinMode(led_3, OUTPUT); // Configuracion del pin led 3 como salida
  pinMode(led_4, OUTPUT); // Configuracion del pin led 4 como salida
  Serial.begin(9600);     // Comunicacion serial a 9600 bps

  // Mensaje inicial
  Serial.println("Ingresar el dato como:");
  Serial.println("Aporcentaje_1,porcentaje_2 o Bporcentaje_3,porcentaje_4");
  Serial.println("Formato: AXXX,YYY");
  Serial.println("Ejemplo: A10,100 (10% y 100%)");
}

void loop() {
  if(Serial.available() > 0){ // Lectura del puerto mientras sigue abierto
    funcion_A(); funcion_B(); // Funcion A y B
    //while (Serial.available() > 0){Serial.read();} // Rutina de limpieza del buffer del puerto serial
  }
}

void funcion_A(){
  if (Serial.peek() == 'A'){ // Discriminacion de la funcion A
    data = Serial.readStringUntil('\n');                   // Lectura del dato hasta el line feed 
    Serial.print("Dato original: "); Serial.println(data); // Muestra del dato original
    data.remove(0,1);                                      // Remueve la letra A
       
    int n, pwm_1, pwm_2; // Variables de almacenamiento de pwm y para algoritmo de lectura
     
    for (int i = 0; i <= data.length(); i++){ // Lectura total del tamano del dato
      if (data.substring(i, i+1) == ","){     // Lectura del dato hasta encontrar el caracter ","
        pwm_1 = data.substring(0, i).toInt(); // Conversion del dato obtenido del porcentaje del pwm 1
        n = i + 1;                            // Posicion de la letra final leida + 1
      }
    }

    // Lectura total del tamano del dato desde el ultimo punto
    for (int i = n; i <= data.length(); i++){ pwm_2 = data.substring(n, i).toInt(); }

    // Muestra del dato del porcentaje de PWM 1 y 2
    Serial.print("Procentaje 1: "); Serial.print(pwm_1); Serial.println(" %");
    Serial.print("Procentaje 2: "); Serial.print(pwm_2); Serial.println(" %");
     
    pwm_1 = map(pwm_1, 0, 100, 0, 255); // Cambio de formato del dato de 0 - 100%, a 0 - 255
    pwm_2 = map(pwm_2, 0, 100, 0, 255); // Cambio de formato del dato de 0 - 100%, a 0 - 255

    // Muestra del dato en pantalla
    Serial.print("PWM 1: "); Serial.println(pwm_1);
    Serial.print("PWM 2: "); Serial.println(pwm_2);

    // Salida PWM en el led de 0 a 255
    analogWrite(led_1, pwm_1); analogWrite(led_2, pwm_2);
  }
}

void funcion_B(){
  if (Serial.peek() == 'B'){ // Discriminacion de la funcion B
    data = Serial.readStringUntil('\n');                   // Lectura del dato hasta el line feed 
    Serial.print("Dato original: "); Serial.println(data); // Muestra del dato original
    data.remove(0,1);                                      // Remueve la letra B
           
    int n, pwm_1, pwm_2; // Variables de almacenamiento de pwm y para algoritmo de lectura
     
    for (int i = 0; i <= data.length(); i++){ // Lectura total del tamano del dato
      if (data.substring(i, i+1) == ","){     // Lectura del dato hasta encontrar el caracter ","
        pwm_1 = data.substring(0, i).toInt(); // Conversion del dato obtenido del porcentaje del pwm 1
        n = i + 1;                            // Posicion de la letra final leida + 1
      }
    }

    // Lectura total del tamano del dato desde el ultimo punto
    for (int i = n; i <= data.length(); i++){ pwm_2 = data.substring(n, i).toInt(); }

    // Muestra del dato del porcentaje de PWM 1 y 2
    Serial.print("Procentaje 3: "); Serial.print(pwm_1); Serial.println(" %");
    Serial.print("Procentaje 4: "); Serial.print(pwm_2); Serial.println(" %");
     
    pwm_1 = map(pwm_1, 0, 100, 0, 255); // Cambio de formato del dato de 0 - 100%, a 0 - 255
    pwm_2 = map(pwm_2, 0, 100, 0, 255); // Cambio de formato del dato de 0 - 100%, a 0 - 255

    // Muestra del dato en pantalla
    Serial.print("PWM 3: "); Serial.println(pwm_1);
    Serial.print("PWM 4: "); Serial.println(pwm_2);

    // Salida PWM en el led de 0 a 255
    analogWrite(led_3, pwm_1); analogWrite(led_4, pwm_2);
  }
}
El programa en Processing es el siguiente:
/* PROGRAMA DE PRUEBA DE COMUNICACION SERIAL
     
   El siguiente programa nos ayuda a enviar el valor pwm de 0 a 100% a un Arduino y
   recibimos en contraparte la confirmacion del valor del PWM de 0 a 255 y el porcentaje

   Autor: Renato Hurtado
   http://beetlecraft.blogspot.pe/
    
   El siguiente programa es de uso publico, cualquier modificacion o mal uso del mismo que pudiera 
   ocasionar el mal funcionamiento de la plataforma de uso de la misma no es responsabilidad del autor
*/

import controlP5.*; // Importacion de la libreria controlP5
ControlP5 cp5;      // Creacion del objeto cp5 para el ControlP5

String[] cabeceraCT = {"PWM 1", "PWM 2", "PWM 3", "PWM 4"}; // Cabecera del campo de texto
String[] cabeceraB = {"Enviar1", "Enviar2"}; // Cabecera de los botones

// Dato de almacenamiento del cuadro de texto y envio
String pwm_1 = "0", pwm_2 = "0", pwm_3 = "0", pwm_4 = "0", data_1, data_2;
short LF = 10; // ASCII linefeed

import processing.serial.*; //Inicio de la comunicación serial
Serial puerto;              // Crea el puerto serial

void setup() {
  size(340, 340); // Porte de la pantalla ancho, alto

  String ArduinoPuerto = Serial.list()[0];        // Encuentra el primer puerto serial para iniciar la comunicacion
  puerto = new Serial(this, ArduinoPuerto, 9600); // Inicio de la comunicacion con el primer puerto encontrado
  
  PFont fuente = createFont( "arial", 15); // Tamano de la fuente y tipo
  
  cp5 = new ControlP5(this); // Inicializacion de la funcion cp5
  
  int y = 20, espaciamiento = 80; // Variables de almacenamiento de coordenada "y" y espaciamiento
  
  for(String nombre: cabeceraCT){
    cp5.addTextfield(nombre)   // Nombre del cuadro de texto
       .setPosition(20, y)     // Ubicacion del boton en la ubicacion x, y
       .setSize(200, 40)       // Tamano del boton ancho, alto
       .setFont(fuente)        // Fuente del texto
       .setAutoClear(false);   // No se limpia el campo de texto con "Enter"
    y += espaciamiento;        // Espaciamiento para el siguiente campo de texto       
  }
  
  y = 100; // reseteo de la ubicacion en y
  
  for(String nombre: cabeceraB){
    cp5.addBang(nombre)     // Nombre del boton
       .setPosition(240, y) // Ubicacion del boton en la ubicacion x, y
       .setSize(80, 40)     // Tamano del boton ancho, alto
       .setFont(fuente);    // Fuente del texto
    y += 2*espaciamiento;   // Espaciamiento para el siguiente campo de texto 
  }
}
 
void draw () {
  String mensaje = puerto.readStringUntil(LF); // Lee todo el mensaje hasta encontrar el linefeed
   
  if (mensaje != null) { // Si el dato no es null
    print(mensaje);      // Muestra en pantalla del mensaje original de Arduino
  }
  
  background(0); // Color de fondo
}
 
void Enviar1() {
  // Lectura del valor obtenido del campo de texto
  pwm_1 = cp5.get(Textfield.class, "PWM 1").getText();
  pwm_2 = cp5.get(Textfield.class, "PWM 2").getText();
  
  // Mensaje de confirmacion de envio del PWM
  println("PWM 1 enviado: " + pwm_1); println("PWM 2 enviado: " + pwm_2);
  data_1 = 'A' + pwm_1 + ',' + pwm_2; // Armado de la data de envio
  puerto.write(data_1); // Escritura del valor del PWM (envio de data al Arduino)
    
  // Borra el cuadro de texto despues de apretar el boton
  cp5.get(Textfield.class, "PWM 1").clear();
  cp5.get(Textfield.class, "PWM 2").clear(); 
}

void Enviar2() {
  // Lectura del valor obtenido del campo de texto
  pwm_3 = cp5.get(Textfield.class, "PWM 3").getText();
  pwm_4 = cp5.get(Textfield.class, "PWM 4").getText();
  
  // Mensaje de confirmacion de envio del PWM
  println("PWM 3 enviado: " + pwm_3); println("PWM 4 enviado: " + pwm_4);
  data_2 = 'B' + pwm_3 + ',' + pwm_4; // Armado de la data de envio
  puerto.write(data_2); // Escritura del valor del PWM (envio de data al Arduino)
    
  // Borra el cuadro de texto despues de apretar el boton
  cp5.get(Textfield.class, "PWM 3").clear();
  cp5.get(Textfield.class, "PWM 4").clear(); 
}
Los resultados son los siguientes:




Autor: 

No hay comentarios:

Publicar un comentario