Robot «Cuadrúpedo AI» controlado por Android

Robot «Cuadrúpedo AI» controlado por Android

¿Que es un robot?

Un robot es un dispositivo electrónico y generalmente mecánico capaz de desempeñar tareas automáticamente, ya sea por medio de supervisión humana directa, a través de un programa predefinido o siguiendo un conjunto de reglas generales establecidas. Existen multitud de robots diseñados para cumplir diferentes objetivos: como brazos robóticos para el montaje de piezas en una fábrica, vehículos aéreos no tripulados o los robots móviles terrestres.

El “cuadrúpedo AI” nace de la idea de dos alumnos con ganas de hacer un proyecto visual, no nos valía un proyecto estanco, que no se moviese, que no llamase la atención, y ahí, aparece el Cuadrúpedo.

El robot esta construido con piezas de plástico, ABS o PLA. Nos decantamos por las piezas de plástico por la sencillez que nos ofrecían las impresoras 3D para crear piezas. Aparte las piezas de plástico son de gran ligereza y lo suficientemente robustas para la estructura del cuadrúpedo. Las piezas de plástico están impresas en las impresoras 3D del ikaslab, gracias a Tumaker.

Las uniones son los servos FUTABA S3003. Estos servos únicamente tienen tres conexiones, alimentación (5v) , masa y control Estos van unidos a las piezas de plástico con tornillos como se puede ver en la siguiente imagen:

Para las patas se corto goma con intención de que no se resbalase por el pavimento, sin esa goma el movimiento del cuadrúpedo habría quedado mermado en exceso. Al principio tuvimos problemas con esto, pensamos que sin goma los movimientos serian naturales y andaría normal, pero resulto que no, se resbalaba y se quedaba en el sitio sin avanzar. Para ello cortamos un trozo de goma y lo pegamos con loctite al ABS de la pata.

Una vez recopiladas todas las piezas el robot queda montado tal que así, únicamente el chasis sin nada de electrónica.

Mientras uno de los componentes del equipo iba montando el esqueleto del robot, el otro iba haciendo los esquemas en Isis y viendo el funcionamiento de este. Para el esquema se utilizo el Arduino Uno puesto que no encontramos la opción de sacar el Mega. El Isis nos proporciono una idea general de como iba a ser el proyecto pero muy virtual y de forma visual.

Para el proyecto se ha utilizado el Arduino mega 2560, principalmente por las salidas PWM de las cuales dispone. El cuadrúpedo esta formado por 9 motores,y esta placa nos los admitía. Ya que con el arduino UNO que habíamos pensado en un principio no tenia tantas salidas PWM para todos los motores.

Una vez teniamos la placa decidimos crear un escudo «shield» para el Mega, para tratar de manipular menos posible la placa de aprendizaje. Intentamos buscar esa Shield por internet pero no dimos con ella, por lo que en Ares nos dispusimos a diseñarla.
Como se ve en la siguiente imagen esta el archivo del diseño en Ares:

Una vez montada la electronica y formado el cuadrupedo nos dispusimos a hacer la parte logica del proyecto, La aplicacion que la controlaria y el codigo para los motores y el ultrasonico.

La tecnología principal de este proyecto es el Bluetooth. Nos decantamos por el bluetooth puesto que necesitábamos algo que no llevase cables y fuese inalámbrico, otro de los factores claves del bluetooth es su simplicidad y la facilidad que Internet ofrece a esta tecnología.

El cuadrúpedo se controla con el móvil mediante un modulo Bluetooth y con un programa creado y diseñado con la aplicación App inventor. El App inventor es una plataforma online para preparar programas, se programa mediante una forma visual y no en código.

Una vez creado el programa App inventor se procederá a su descarga, se nos bajara un archivo .apk  y lo pasaremos al dispositivo Android, únicamente solo con que ejecutemos ese apk se nos instala Nos aparecerá así en nuestro móvil:

La interfaz creada sera tal que asi y se vera de esta forma sencilla:

En el vídeo se observa el programa, y dependiendo los botones que se pulsen el  cuadrúpedo reaccionará de una manera u otra. El programa de Android esta formado por diferentes botones que se explican en el video, excepto dos botones, reset y stop. La primera función es que se quede en el suelo con las piernas abiertas, y stop, es un modo en el que el cuadrúpedo queda apoyado con las cuatro patas pero de forma relajada.

Dispone de un modulo ultrasónico HC-SR04 que permite al cuadrúpedo andar de forma libre, en modo solitario, pero cuando se encuentra con un objeto delante de el, esquivarlo de manera natural para poder seguir andando y moviéndose por el entorno que le rodea.

Según el programa cuando el ultrasónico detecta algún obstáculo a menos de 30cm el cuadrúpedo se dirige hacia atrás.

En el vídeo anterior se observa el programa Android, explicando brevemente lo que ocurre al pulsar los diferentes botones que forman el programa, con su correspondiente reacción del cuadrúpedo.

Como anexo os adjuntamos el programa que hemos utilizado:

#include <Servo.h>
Servo myservoA;  // create servo object to control a servo
Servo myservoB;
Servo myservoC;
Servo myservoD;
Servo myservoE;
Servo myservoF;
Servo myservoG;
Servo myservoH;
Servo myservoQ;
long medir1;
long medir2;
long medir3;
int TrigPin = 12;
int EchoPin = 13;
int A = 90;  //A – Cadera 1
int B = 90;  //B – Cadera 3
int C = 90;  //C – Cadera 5
int D = 90;  //D – Cadera 7
int E = 90;  //E – Pie 2
int F = 90;  //F – Pie 4
int G = 90;  //G – Pie 6
int H = 90;  //H – Pie 8
int Q = 90;
int incomingByte = 0;
#include <SoftwareSerial.h>
SoftwareSerial mySerial(19, 18); // RX, TX
void setup()
{
   // Open serial communications and wait for port to open:
  Serial.begin(9600);
  pinMode(TrigPin,OUTPUT);
  pinMode(EchoPin,INPUT);
  Serial.println(«Hello «);
  Serial.println(«attaching to port_b»);
  myservoA.attach(9);  // attaches the servo on pin 9 to the servo object
  myservoB.attach(8);  // attaches the servo on pin 9 to the servo object
  myservoC.attach(6);  // attaches the servo on pin 9 to the servo object
  myservoD.attach(7);  // attaches the servo on pin 9 to the servo object
  myservoE.attach(2);  // attaches the servo on pin 9 to the servo object
  myservoF.attach(3);  // attaches the servo on pin 9 to the servo object
  myservoG.attach(4);  // attaches the servo on pin 9 to the servo object
  myservoH.attach(5);  // attaches the servo on pin 9 to the servo object
  myservoQ.attach(11);
}
void loop()
{
  long distance;
  distance=medir();
  Serial.print(  medir() );//Serial display distance
  //Serial.print(«cm»);
  Serial.println();
  //delay(1000);
  if (Serial.available() > 0)
  {
    incomingByte = Serial.read();
    Serial.print(«He recibido:»);
    Serial.println(incomingByte,DEC);
  }
 if (incomingByte==0)
  {
    Serial.print(medir());//Serial display distance
    Serial.print(«dm»);
    Serial.println();
  // delay(500);
  }
  if(medir() ==0)
  {
    if (Serial.available() > 0) {
    incomingByte = Serial.read();
    Serial.print(«He recibido:»);
    Serial.println(incomingByte,DEC);
    // delay(500);
    }
  }
if((medir()<80) &( medir()>=30))
{
   cycle_Stop();
   Serial.println();
   cycle_girar();
   Serial.println();
   Serial.print(  medir2);
   Serial.print(«d2mD»);
   Serial.println();
   Serial.print(  medir3);
   Serial.print(«d3mD»);
   Serial.println();
   //delay(1000);
}
   while((medir2>=medir3)&(medir()<80) &( medir()>=30)&(incomingByte==55))
  {
    cycle_Derecha();
    if (Serial.available() > 0)
    {
      incomingByte = Serial.read();
      Serial.print(«He recibido:»);
      Serial.println(incomingByte,DEC);
    }
    distance=medir();
    Serial.print(  medir());//Serial display distance
    Serial.print(«d1mD»);
    Serial.println();
    Serial.print(  medir2);
    Serial.print(«d2mD»);
    Serial.println();
    Serial.print(  medir3);
    Serial.print(«d3mD»);
    Serial.println();
   // delay(2000);
  }
   while((medir2<medir3)&(medir()<80) &( medir()>=30)&(incomingByte==55))
  {
    cycle_Izquierda();
    if (Serial.available() > 0)
    {
      incomingByte = Serial.read();
      Serial.print(«He recibido:»);
      Serial.println(incomingByte,DEC);
    }
    distance=medir();
    Serial.print(  medir());//Serial display distance
    Serial.print(«d1mZ»);
    Serial.println();
    Serial.print(  medir2);
    Serial.print(«d1mZ»);
    Serial.println();
    Serial.print(  medir3);
    Serial.print(«d1mZ»);
    Serial.println();
    //delay(2000);
  }
 if (( medir()<30 )&(incomingByte==55))
  {
    while (( medir()<60 )&(incomingByte==55))
    {
    cycle_Atras();
    if (Serial.available() > 0)
    {
      incomingByte = Serial.read();
      Serial.print(«He recibido:»);
      Serial.println(incomingByte,DEC);
    }
    distance=medir();
    Serial.print( medir() );//Serial display distance
    Serial.print(«d0m»);
    Serial.println();
   // delay(1000);
    }
  }
    while((medir() >=80)&(incomingByte==55))
  {
    cycle_Avance();
    distance=medir();
    Serial.print(medir());//Serial display distance
    Serial.print(«d2m»);
    Serial.println();
    //delay(3000);
    if (Serial.available() > 0 )
    {
      incomingByte = Serial.read();
      Serial.print(«He recibido:»);
      Serial.println(incomingByte,DEC);
                       
    }                   
   }
  
   while (incomingByte==50)
   {
     cycle_Avance();
       if (Serial.available() > 0) {
      incomingByte = Serial.read();
       Serial.print(«He recibido:»);
       Serial.println(incomingByte,DEC);
       }
     
   }
  
 
     while (incomingByte==53){
      cycle_Stop();
      if (Serial.available() > 0){
      incomingByte = Serial.read();
       Serial.print(«He recibido:»);
       Serial.println(incomingByte,DEC);
      }
     
    }
  while (incomingByte==49){
      cycle_Atras();
      if (Serial.available() > 0){
      incomingByte = Serial.read();
       Serial.print(«He recibido:»);
       Serial.println(incomingByte,DEC);
      }
     
    }
   
     while (incomingByte==56){
      cycle_Derecha();
      if (Serial.available() > 0){
      incomingByte = Serial.read();
       Serial.print(«He recibido:»);
       Serial.println(incomingByte,DEC);
      }
       
    }
   while (incomingByte==52){
      cycle_Izquierda();
      if (Serial.available() > 0){
      incomingByte = Serial.read();
       Serial.print(«He recibido:»);
       Serial.println(incomingByte,DEC);
      }
      
    }
   while (incomingByte==48){
      cycle_Reset();
      if (Serial.available() > 0){
      incomingByte = Serial.read();
       Serial.print(«He recibido:»);
       Serial.println(incomingByte,DEC);
      }
      
    }
     while (incomingByte==54){
      cycle_Avance2();
      if (Serial.available() > 0){
      incomingByte = Serial.read();
       Serial.print(«He recibido:»);
       Serial.println(incomingByte,DEC);
      }
      
    }
}
void   cycle_Avance(){
   for(A = 90; A < 150; A += 60)  // goes from 30 degrees to 150 degrees
  { 
    myservoE.write(40);
    myservoH.write( 140);
    myservoF.write(0);
    myservoG.write(0);
    delay(200);     // in steps of 10 degree
    myservoA.write(30);              // tell servo to go to position in variable ‘A’
    myservoD.write(90);
    myservoB.write(150);
    myservoC.write(90);
    delay(200);
                 // waits 15ms for the servo to reach the position
  }
  for(A = 150; A>=91; A-=60)     // goes from 150 degrees to 30 degrees
  {                                
    
    myservoF.write(40);
    myservoG.write(40);
    myservoE.write(0);
    myservoH.write(180);
      delay(200);
    myservoA.write(90);              // tell servo to go to position in variable ‘A’
    myservoD.write(30);
    myservoB.write(90);
    myservoC.write(150);   
    delay(200);             // waits 15ms for the servo to reach the position
  }
   Serial.print(«Avance»);
  }
void cycle_Stop(){
   myservoE.write( 0);
    myservoH.write(180);
    myservoF.write(0);
    myservoG.write(0);
    myservoA.write(90);              // tell servo to go to position in variable ‘A’
    myservoD.write(90);
    myservoB.write(90);
    myservoC.write(90);
    //delay(1000);
    Serial.print(«Stop»);
  }
void cycle_Reset(){
    for(A = 90; A < 150; A += 1)  // goes from 30 degrees to 150 degrees
  {                           // in steps of 10 degree
  
    myservoE.write( 90);
    myservoH.write(90);
    myservoF.write(90);
    myservoG.write(90);
    myservoA.write(90);              // tell servo to go to position in variable ‘A’
    myservoD.write(90);
    myservoB.write(90);
    myservoC.write(90);
   
    delay(20);    
                      // waits 15ms for the servo to reach the position
  }
 for(A = 150; A>=91; A-=1)     // goes from 150 degrees to 30 degrees
  {                              
    myservoF.write(90);
    myservoG.write(90);
    myservoE.write(90);
    myservoH.write(90);
    myservoA.write(90);              // tell servo to go to position in variable ‘A’
    myservoD.write(90);
    myservoB.write(90);
    myservoC.write(90);
   
    delay(20);   
                      // waits 15ms for the servo to reach the position
  }
}
void   cycle_Atras(){
  for(A = 90; A < 150; A += 60)  // goes from 30 degrees to 150 degrees
  { 
    myservoE.write(0);
    myservoH.write( 180);
    myservoF.write(40);
    myservoG.write(40);
    delay(200);     // in steps of 10 degree
    myservoA.write(30);              // tell servo to go to position in variable ‘A’
    myservoD.write(90);
    myservoB.write(150);
    myservoC.write(90);
    delay(200);
                 // waits 15ms for the servo to reach the position
  }
  for(A = 150; A>=91; A-=60)     // goes from 150 degrees to 30 degrees
  {                                
    
    myservoF.write(0);
    myservoG.write(0);
    myservoE.write(40);
    myservoH.write(140);
      delay(200);
    myservoA.write(90);              // tell servo to go to position in variable ‘A’
    myservoD.write(30);
    myservoB.write(90);
    myservoC.write(150);   
    delay(200);             // waits 15ms for the servo to reach the position
  }
   Serial.print(«Atras»);
}
void   cycle_Avance2(){
   for(A = 90; A < 150; A += 60)  // goes from 30 degrees to 150 degrees
  { 
    myservoE.write(40);
    myservoH.write( 140);
    myservoF.write(0);
    myservoG.write(0);
    delay(150);     // in steps of 10 degree
    myservoA.write(60);              // tell servo to go to position in variable ‘A’
    myservoD.write(120);
    myservoB.write(120);
    myservoC.write(60);
    delay(150);
                 // waits 15ms for the servo to reach the position
  }
  for(A = 150; A>=91; A-=60)     // goes from 150 degrees to 30 degrees
  {
    myservoF.write(40);
    myservoG.write(40);
    myservoE.write(0);
    myservoH.write(180);
      delay(180);
    myservoA.write(120);              // tell servo to go to position in variable ‘A’
    myservoD.write(60);
    myservoB.write(60);
    myservoC.write(120);   
    delay(180);             // waits 15ms for the servo to reach the position
  }
   Serial.print(«Avance»);
  }
void   cycle_Izquierda(){
  for(A = 90; A < 150; A += 60)  // goes from 30 degrees to 150 degrees
  {
    myservoE.write(40);
    myservoH.write( 140);
    myservoF.write(0);
    myservoG.write(0);
    delay(180);     // in steps of 10 degree
    myservoA.write(60);              // tell servo to go to position in variable ‘A’
    myservoD.write(90);
    myservoB.write(90);
    myservoC.write(90);
    delay(180);
                 // waits 15ms for the servo to reach the position
  }
  for(A = 150; A>=91; A-=60)     // goes from 150 degrees to 30 degrees
  {
    myservoF.write(40);
    myservoG.write(40);
    myservoE.write(0);
    myservoH.write(180);
      delay(150);
    myservoA.write(90);              // tell servo to go to position in variable ‘A’
    myservoD.write(60);
    myservoB.write(90);
    myservoC.write(150);   
    delay(150);             // waits 15ms for the servo to reach the position
  }
    Serial.print(«Izquierda»);
}
void  cycle_Derecha(){
  for(A = 90; A < 150; A += 60)  // goes from 30 degrees to 150 degrees
  {
    myservoE.write(0);
    myservoH.write( 180);
    myservoF.write(40);
    myservoG.write(40);
    delay(200);     // in steps of 10 degree
    myservoA.write(90);              // tell servo to go to position in variable ‘A’
    myservoD.write(90);
    myservoB.write(90);
    myservoC.write(120);
    delay(200);
                 // waits 15ms for the servo to reach the position
  }
  for(A = 150; A>=91; A-=60)     // goes from 150 degrees to 30 degrees
  {                               
    
    myservoF.write(0);
    myservoG.write(0);
    myservoE.write(40);
    myservoH.write(140);
      delay(200);
    myservoA.write(30);              // tell servo to go to position in variable ‘A’
    myservoD.write(90);
    myservoB.write(120);
    myservoC.write(90);   
    delay(200);             // waits 15ms for the servo to reach the position
  }
   Serial.print(«derecha»);
}
long medir(void)
{
  
  long dist,duration;
  digitalWrite(TrigPin,HIGH);//TrigPin prepare high of more than 10us
  delayMicroseconds(11);
  digitalWrite(TrigPin,LOW);
  duration = pulseIn(EchoPin, HIGH);//EchoPin received high start counting until the receiver to the low,return to the count valu
  dist = duration/29/2;//Calculating the distance  cm
                           // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  return dist;
}
void cycle_girar(){
  
  myservoQ.write(0);   //Cargamos la funcion con el valor en grados de 0 a 179º
  delay(200);
  medir2=medir();
  delay(200);        //Retardo entre coordenadas
  myservoQ.write(90);  //Cargamos la funcion con el valor en grados de 0 a 179º
  delay(200);
  medir1=medir();
  delay(200);  //Retardo entre coordenadas
  myservoQ.write(179); //Cargamos la funcion con el valor en grados de 0 a 179º
  delay(200);
  medir3=medir();
  delay(200);        //Retardo entre coordenadas
  myservoQ.write(90);  //Cargamos la funcion con el valor en grados de 0 a 179º
  delay(200);
   Serial.print(«girar»);

 

  }
TWI-TWI, impresora 3D controlada por Android

TWI-TWI, impresora 3D controlada por Android

¿Que es el proyecto TWI – TWI?

De manera sencilla y resumida, la Voladora V2 de Tumaker utiliza una placa llamada Megatronics V3, simplemente es un Arduino Mega 2560 con los pines adaptados para controlar impresoras 3D. Se le ha añadido un modulo Bluetooth a la placa electrónica y se ha creado una aplicación, mediante el programa App Inventor de Google, para controlar la impresora 3D Voladora V2 de Tumaker desde cualquier periférico que utilice el sistema operativo Android.

El objetivo de este proyecto es desarrollar y construir un periférico que controle una impresora 3D, exactamente, la Voladora V2 de Tumaker.

Este proyecto esta formado por tres partes, la comunicación entre el móvil y la impresora 3D Voladora V2 de Tumaker, la aplicación que se crea con App Inventor y el firmaware (el programa que se carga en la placa Megatronics V3) que se llama Marlin.

Comunicación Bluetooth y comunicación Serie
La comunicación  Bluetooth es un protocolo de comunicación inalámbrica de voz y datos.

La comunicación Serie o Serial es un protocolo de comunicación mediante cables de voz y datos que se envía y recibe mediante RX y Tx.

El proyecto TWI – TWI funciona,se envían «comandos» desde el móvil, a la impresora 3D y viceversa. El modulo Bluetooth hace de intermediario entre la impresora 3D y el móvil. El modulo Bluetooth recibe los «comandos» desde el móvil y la impresora 3D. Se utilizan dos tipos de comunicación, la comunicación Serie y la comunicación Bluetooth. La comunicaciòn entre el móvil y el modulo Bluetooth es comunicación Bluetooth, es decir, la información es enviado mediante ondas y la comunicación entre el modulo Bluetooth y la impresora 3D es una comunicación Serie.

Programación

En este proyecto se ha llevado a cabo modificando el Marlin en el sketch de Arduino, el lenguaje en el que se basa Arduino es en C y C++.

Arduino es una plataforma de hardware libre, basada en una placa con un microcontrolador y un entorno de desarrollo, diseñada para facilitar el uso de la electrónica en proyectos multidisciplinares.

Firmware (Marlin)

Firmware es un programa que es grabado en una memoria, normalmente de lectura/escritura (ROM, EEPROM, flash, etc.), que establece la lógica de más bajo nivel que controla los circuitos electrónicos de un dispositivo de cualquier tipo.
El firmware que utiliza la impresora 3D Voladora V2 de Tumaker es uno llamado Marlin. El mismo firmware sirve para diferentes impresoras 3D, pero se tiene que modificar adaptándolo a la impresora 3D en funciones.

El primer y gran dilema de este proyecto es que se tiene que crear un nuevo puerto serie, muchos os preguntareis porque si puedes utilizar el puerto serie que trae predeterminado la placa. Si se utiliza el mismo puerto serie, la trasmisión de datos se colapsa y ademas no se podrá utilizar la impresora 3D mediante el uso normal, para ello se modifica el firmware «Marlin». La placa electrónica Megatronics V3 de la impresora 3D te da la opción de abrir puertos serie mediante software y hardware.

Los trozos de programa que se modifica en el Marlin.

#include "NewSoftSerial.h"  // Llamada a la libreria NewSoftSerial
#define rxPin 11  //  Declara el pin 11 con el nombre de rxPin
#define txPin 15  //  Declara el pin 15 con el nombre de rxPin
NewSoftSerial miSerial(rxPin, txPin);  //  declara en nombre del puerto serie y define los pines rx y tx

void setup()
{
  miSerial.begin(9600);  // Abre en nuevo puerto serie
  pinMode(3,INPUT);  // declara el pin 3 como entrada
  pinMode(2,OUTPUT);  // declara el pin 2 como salida
  pinMode(rxPin, INPUT); // declara el pin rxPin como entrada
  pinMode(txPin, OUTPUT); // declara el pin txPin como salida

Con el trozo de código de arriba  se consigue abrir el nuevo puerto serie y en este caso el pin 11 es Rx y el pin 15 es Tx. Sin olvidar la velocidad en baudios del nuevo puerto serie, en este caso es de 9600 baudios, es una de las razones por las que puede que al dibujar a mano alzada la impresión se atasque, ya que la impresora 3D y el ordenador se comunican a 115200 baudios. 12 veces mas lento.

void loop()

{
 int estado;  // crear una variable con el nombre estado
 estado=digitalRead(3);  // guardar la lectura del pin 3 en la variable estado
 switch(estado) // mira el valor de la variable estado y ejecutara lo que este dentro del caso 0: caso 1: ...
 {
   case 0: //  ejecutara lo que este dentro siempre que el valor de estado sea 0

   if(buflen < (BUFSIZE-1))


     get_command();
   #ifdef SDSUPPORT
   card.checkautostart(false);
   #endif
   if(buflen)
   {
     #ifdef SDSUPPORT
       if(card.saving)
       {
  if(strstr_P(cmdbuffer[bufindr], PSTR("M29")) == NULL)
  {
    card.write_command(cmdbuffer[bufindr]);
    SERIAL_PROTOCOLLNPGM(MSG_OK);
  }
  else
  {
    card.closefile();
    SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED);
  }
       }
       else
       {
  process_commands();
       }
     #else
       process_commands();
     #endif //SDSUPPORT
     buflen = (buflen-1);
     bufindr = (bufindr + 1)%BUFSIZE;
   }
   //check heater every n milliseconds
   manage_heater();
   manage_inactivity();
   checkHitEndstops();
   lcd_update();
          break;

   case 1:

 if(buflen < (BUFSIZE-1))


  get_command_bluetooth();
   #ifdef SDSUPPORT
   card.checkautostart(false);
   #endif
   if(buflen)
   {
     #ifdef SDSUPPORT
       if(card.saving)
       {
  if(strstr_P(cmdbuffer[bufindr], PSTR("M29")) == NULL)
  {
    card.write_command(cmdbuffer[bufindr]);
    SERIAL_PROTOCOLLNPGM(MSG_OK);
  }
  else
  {
    card.closefile();
    SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED);
  }
       }
       else
       {
  process_commands();
       }
     #else
       process_commands();
     #endif //SDSUPPORT
     buflen = (buflen-1);
     bufindr = (bufindr + 1)%BUFSIZE;
   }
   //check heater every n milliseconds
   manage_heater();
   manage_inactivity();
   checkHitEndstops();
   lcd_update();
          break;
  
  
}

}

void get_command_bluetooth() // es una funcion que se ha creado para interpretar los datos recibidos desde el móvil y ejecutar las acciones
{ 
  while( miSerial.available() > 0  && buflen < BUFSIZE) { // mientras reciba algo superior a 0 por el puerto serie
    serial_char = miSerial.read();

Dentro del Void loop, que es la función principal, se crea este trozo de código para elegir mediante un interruptor la forma de utilizar la impresora 3D Voladora V2 de Tumaker, de manera normal, es decir, controlado por ordenador o controlado por el móvil.

Se ha creado la función void get_command_bluetooth() para interpretar los datos recibidos desde el móvil y ejecutar las acciones.

Se ha creado la función void get_command_bluetooth() para interpretar los datos recibidos desde el móvil y ejecutar las acciones.

App Inventor

App Inventor es un entorno de desarrollo visual de aplicaciones para los teléfonos Android desarrollado por el MIT. Para desarrollar aplicaciones con App Inventor sólo necesitas un navegador web y un teléfono Android.

Al construir las aplicaciones para Android se trabaja con dos herramientas: App Inventor Designer y App Inventor Blocks Editor. En Designer se construye el Interfaz de Usuario, eligiendo y situando los elementos con los que interactuará el usuario. Con el Blocks Editor se define el comportamiento de los componentes de la aplicación.

Esta es la parte visual de la aplicación se ha creado utilizando la herramienta Designer, simplemente son botones, textBox (que es un texto vació para rellenar), texto.

En la imagen de abajo se aprecia el programa entero, mediante el editor de bloques conseguimos asignar acciones a los diferentes objetos de la parte visual.

Todos los bloques tienen una condición, si el modulo bluetooth esta conectado, entonces ejecuta las acciones.

Componentes

-Modulo Bluetooth
-Interruptor
-Voladora V2
-Móvil sistema operativo Android
-Tarjeta SD

Cambios en la impresora 3D Voladora V2 de Tumaker

Se ha modificado la impresora 3D Voladora V2 de Tumaker físicamente para llevar a cavo este proyecto.

Utilizando un pin digital libre de la placa Megatronics V3 se ha colocado un interruptor en forma de pull-up, cuando el interruptor este levantado significa que se controla desde el ordenador y cuando el interruptor este abajo significa que se controla desde el móvil.
Aparte de colocar el interruptor es necesario conectar el modulo Bluetooth e introducir la tarjeta SD con algún G-code cargado en la tarjeta SD.
Esquema de Megatronics V3
En el esquema de arriba se aprecia el conexionado de la placa Megatronics V3, los pines del modulo Bluetooth se conectan Rx al pin 11 y Tx al pin 15 y dos mas que son 5v y 0v.
El interruptor con el sistema pull-up se conecta en el pin 2.

Descargar archivos del proyecto.

RASPZEPPELIN, Dron controlado por Android

RASPZEPPELIN, Dron controlado por Android

Proiektu honen helburua jendetza handiko jazoeratan iragarkiak ahalik eta jende gehienari iritsi ahal izatea da, baina baita ere ingurugiroko datuak hartu eta imaginak denbora errealean gure Android gailura bidaltzea.
Zeppelina Wifi bidez dago konektaturik Android gailu mugikorrera. Android gailuan Zeppelina kontrolatzeko sortutako aplikazio bat egozten da, aplikazio honen bidez Zeppelinarekin interaktuatu ahal izango dugu.

 

Aplikazio honek Zeppelinaren kontrolaz gain beste ainbat datu ere erreztuko dizkigu, horietatik garrantzitsuena denbora errealean jasotako bideoa da.

RaspZeppelinaren egituran Raspberry Pi bat dago kontrolaz arduraturik. Raspberry Pi bat, Hardware libreko SBC bat da eta Linuxen oinarrituriko sistema eragilea erabiltzen du. Sofwar hau librea denez, proiektu honentzako aproposa da gure nahietara egoki baitezakegu. Raspberriaren funtzio nagusiak ondorengoak dira: Arduino mikrokontrolatzaileari egin beharrekoa adieraztea, Acces Point bezela jokatzea gailu mugikorrarekin wifi konexioa lortzeko eta kamararen kontrolaz arduratzea. Wifi konexia lortzeko Wi-Pi wifi moduloa erabili da.

Raspberry Piaren aginduak Arduino Mega plakara doaz. Arduino Mega ATmega2560 mikrokontrolagailu batetan oinarrituriko plaka bat da. Plaka honek agindu bakoitzeko irteera bat edo beste aktibatuko du bere barnean duen programari esker.

Arduino plakak azkenik aktuadoreei bidaliko die agindua. Aktuadoreak RaspZeppelinaren norabidea eta kameraren kontrola erregulatuko dute. 5V-ko bi servomotorek kameraren angelua eta propultsio servoen angelua kontrolatuko dute. 5V-ko ak direnez zuzenean lotu daitezke Arduino Megarekin. Beste bi brushless motore RaspZeppelinaren propulsioaz arduratuko dira. Hauek Arduino plaka eta beraien artean control etapa bat dute, ESC zirkuito elektroniko bat. Azkenik RaspZeppelinaren norabidea kontrolatzeko DC-ko 5v-ko motore bat hau isatsan dagoenez RaspZeppelina altuera konstate batean geldirik egonik bere Z ardatzarekiko biratzea ahalbidetzen du. Zuzenki polarizatzen denean zentzu batean biratzen du eta alderantziz polarizatzean beste alderuntz biratzen du.

Hurrengo lerroetan proiektua gartzeko eman ditugun pausuak:

1. Eskemaren edizioa eta Zirkuituaren simulazioa:

RaspZeppelinaren Arduinoko programa simulatzeko, Isis-en sortutako eskema bat beharrezkoa da programan egon daitezkeen akatsak aurrez topatzeko. Isis-eko programak serboak zuzenean konektatzea onartzen duen arren, brushless motoreen eta Arduinoaren artean, ESC etapa bat beharrezkoa da.

2. PCB-aren fabrikazioa:

Areseko PCB-a método mekaniakoren bidez eraiki da. Areseko artxiboa, .LYT izeneko extensioa dauka, baina extensio hau irakurezina da Board Master programan. Artxiboa egokitzeko CircuitCam-en .LMD extensiora pasa da, Board Master-ek irakur ahal dezan. Board Masterren LPKF-aren lan sistema konfiguratzen da eta fresatu beharrekoa adierazten zaio LPKF-ari.

Lehenik eta behin zuloak egiten dira metalizatu ahal izateko, metalizatu prosezua pasa eta gero, berriz LPKF-ra eramaten dugu plaka, bi aldeetako pistak egiteko.

3. Konponenteen kokapena eta soldadura:

Behin PCBaren plaka eraikita, konponenteak jarri eta soldatu dira, ondorengo argazkian eraikitako Shiedaren irudi bat.

4. Arduinoren programazioa:

#include <Servo.h>
Servo servokamera;          //altuera kontrolatzeko servoa
Servo servoaltuera;         //kamera kontrolatzeko servoa
Servo esc7;                //nombramos el esc7. Aurrera
Servo esc8;                //nombramos el esc8. Aurrera
int motor1=6;              //Direccion
int motor2=5;               //Direccion
float bateria=A1;         //asignamos al pin A1 la entrada de la bateria
int estadobateria=0;
int ledbateriabaja=4;     //asignamos el pin 4 a los led bateriabaja
float estadobateriav;
int F=’J’;
int kamerakontrol =500; //Poner servo de camara en posición «0»

void setup (){

servoaltuera.attach(10); //asignamos el pin 10 al servoaltuera
servokamera.attach(9); //asignamos el pin 9 al servokamera
esc7.attach(7);   //asignamos el pin 7 al esc11
esc8.attach(8);  //asignamos el pin 8 al esc12
pinMode(motor1, OUTPUT);   //Direccion
pinMode(motor2, OUTPUT);   //Direccion
pinMode (A1,INPUT); //pin analogico para control bateria
pinMode (4,OUTPUT);  //pin para encender leds de aviso

esc7.write(0);    //Armamos el esc11 enviandole «0»
esc8.write(0);   //Armamos el esc12 enviandole «0»
delay (1000);
esc7.write (20);  //Le enviamos «20» y se escucha un pitido
esc8.write (20);   //Le enviamos «20» y se escucha un pitido
delay(1000);
Serial.begin (9600);
digitalWrite(ledbateriabaja,LOW);
}

void loop(){
estadobateria = analogRead(bateria); //leer bateria y escribir en estadobateria
estadobateriav = estadobateria * (5.0 / 1023.0); //conversión de lectura
if(estadobateriav < 4.18){
digitalWrite(ledbateriabaja,HIGH);
//mandar informacion a raspi
}
else{
digitalWrite(ledbateriabaja,LOW);
}

Serial.print( » «);
Serial.println( » «);
Serial.print(estadobateriav);   //escribe en purto serial valor de la bateria

if (Serial.available() > 0) {
F = Serial.read();
}
switch(F){
case ‘A’:
mover(90,40,40,0,0);     //A letra ASCII, gora juteko
break;
case ‘B’:
mover(180,40,40,0,0);    //B letra ASCII, behera juteko
break;
case ‘C’:
mover(45,40,40,0,0);     //C letra ASCII, aurrera juteko
break;
case ‘D’:
mover(135,40,40,0,0);     //D letra ASCII, atzera juteko
break;
case ‘E’:
mover(0,20,20,255,0);    //E letra ASCII, eskubira juteko
break;
case ‘F’:
mover(0,20,20,0,255);    //F letra ASCII, ezkerrera juteko
break;
case ‘G’:
mov_camara(1,50);        //G letra ASCII, kamera behera juteko
break;
case ‘H’:
mov_camara(0,50);        //H letra ASCII, kamera gora juteko
break;
case ‘I’:
mov_camara(1,0);         //I letra ASCII, kamera GERATU
break;
case ‘J’:
mover(0,20,20,0,0);      //J letra ASCII, dena gelditzeko
break;
}
}

/************************************************************
funcion para control del movimiento del Zepellin
Le pasamos 5 parametros:
ang_motores  (0-180)
vel_esc7     (20-180)
vel_esc8     (20-180)
motor_cola_izq  (0-255)
motor_cola_dch  (0-255)
***********************************************************/

void mover(int ang_motores,int vel_esc1,int vel_esc2,int motor_cola_izq,int motor_cola_dch  ){

servoaltuera.write(ang_motores);
esc7.write(vel_esc1);          //Damos marcha al motot a «90»
esc8.write( vel_esc2);          //Damos marcha al motot a «90»
analogWrite(motor1, motor_cola_izq);   //Direkzioa 0ra
analogWrite(motor2, motor_cola_dch);   //Direkzioa 0ra
}

/***********************************************************
función para control del movimiento de la camara
Le pasamos dos parametro:
direccion (1 –> suma , 0 –> resta)
var_angulo  (0 a 50)
************************************************************/
void mov_camara (int direccion, int var_angulo) {

if(direccion==1){
kamerakontrol = kamerakontrol + var_angulo;
}
else{
kamerakontrol = kamerakontrol – var_angulo;
}
servokamera.writeMicroseconds (kamerakontrol);
delay (500);
}

4. Android Aplikazioa:

Eclipse programa erabiliz, edozein mugikor edo tabletekin Zeppelina guidatu ahal izateko aplikazio bat garatu dugu. Tablet bertatik Zeppelina guztiz gidatzeaz gain, bideoa ikusi daiteke eta argazkiak atera ere bai.

5. Materialen metaketa:

• Arduino mega 2560
• Raspberry-py
• Raspberry-ren kamera
• 2xBrushless motore
• 2xESC
• Servo Motor
• Micro Servo
• Arduino megarentzat Shield-a
• 3xDiodo led
• 1xInterruptore
• 1xResistencia 10K
• 3xResistencia 330 ohm.
• 2xBaterias lipo de tres celdas y 2200mA
• H Zubia


6. Prototipoaren kableaketa eta froga:

Behin servo guztiak eta korronte zuzenezko motorea kontrolatutak dauzkagunean, denak elkarrekin frogatzera pasako gara.

7. 3D Osagaien diseinu eta fabrikazioa:

3D inpresoran sortutako konponenteak asko izan dira RaspZeppelinean. Serboen kontrolarako engranaiak, brushlessak eje transmisorera lotzeko piezak, zeppelinaren hegalak, isatseko motorraren gurutze hegalak, elektronika sartzeko gondola, gondolaren ankak eta kamera lotzeko kutxa.

Diseinatu ditugun pieza guztien .stl artxiboak blog-aren bukaerako link-aren barruan daude.

8. Heliorekin betetzea:

Heliorekin puzteko orduan, kontuz ibili behar da helio botilak presio handia duelako barruan eta gaizki erabiltzea oso arriskutsua delako.

9. Lehenengo hegalaldiak:

Azkenik, frogatzeko hegalaldi frogak egin ditugu funtzionamendua ona delako bermatzeko.

Deskargatu proiektuko artxiboak.

Programador de ESC con arduino

Programador de ESC con arduino

Para el control de los motores brushless, ampliamente utilizados en radiocontrol, se utiliza un circuito electrónico denominado ESC.


Estos controladores se programan con una emisora de Radio Control y su correspondiente receptor al que conectamos el ESC. Una vez programados, se controlan como si fueran servos normales.
Hay una serie de códigos acústicos a base de pitidos que emite el ESC con los que sabemos los parámetros que estamos configurando.
Habrá que consultar el datasheet del ESC para conocer esos códigos.

Para nuestro proyecto (un zepellin) no necesitabamos la emisora, ya que pensamos controlar el zepellin desde una tablet por WIFI. El control lo haremos con un arduino y una RaspberryPi.

Aquí os presentamos un circuito con arduino UNO que nos permite programar los ESC sin necesidad de comprarnos una emisora de RC. Dispone de tres botones que hacen el efecto de mando al máximo, medio y mínimo que genera el mando de RC. Os dejamos el esquema y el programa del arduino. Sólo hay que conectar el ESC y seguir los códigos de pitidos para programarlos como nos interese.

Aquí va el programa que hay que cargar en el arduino:

#include <Servo .h>

Servo esc;

int ACELERAMAX;
int ACELERAMED;
int ACELERAMIN;
void setup(){
pinMode (2,INPUT);
pinMode (3,INPUT);
pinMode (4,INPUT);
esc.attach (9);
// esc.writeMicroseconds(0);
Serial.begin (9600);
}
void loop() {
ACELERAMIN = digitalRead(2);
ACELERAMED = digitalRead(3);
ACELERAMAX = digitalRead(4);

if(ACELERAMAX == 0) {
esc.writeMicroseconds(1990);
Serial.println («Max»);
}

else if(ACELERAMED == 0) {
esc.writeMicroseconds(1470);
Serial.println («Med»);
}

else if(ACELERAMIN == 0) {
esc.writeMicroseconds(1130);
Serial.println («Min»);
}

}