Vistas de página en total

viernes, 13 de noviembre de 2015

Robot 2W controlado por ESP8255

   Tenía pensado espera a tener acabado una rutina para controlar el robor en wifi, pero debido a la falta de tiempo, no puedo pasar el código inicial que hice, y que está aquí a la versión posterior con bluetooth que he puesto en la entrad anterior.
    Por ello, debido a que me han pdido un código para mover un robot mandado por ESP8266, pongo el código, tal como lo tenía en el vido de youtube, para que pueda ampliarlo y terminarlo el que lo desee.

    Igualmente coloco el MainActivity del Android del programa que está en el video.





Código Arduino Main.
#include <SoftwareSerial.h>
#include <ESP8266.h>
#include <Ultrasonic.h>
#include <Servo.h>
#include <Wire.h>
#include "Robot.h"

     


#define PASSWORD "xxxxxxxxxxxxxxxxxx"
#define SSID "xxxxxxxxxxxx"



//#define control_automatico
#define control_wifi

SoftwareSerial esp8266Serial = SoftwareSerial(10, 11);
ESP8266 wifi = ESP8266(esp8266Serial);

Robot MyRobot=Robot();


void setup() {
   
  Serial.begin(9600);
  esp8266Serial.begin(9600);
  Serial.println("Realizando Setup");
 setup_wifi();
  MyRobot.Init();
  MyRobot.Stop();
  
}

 void loop() {
unsigned int id;
int comando,i;
int length;
int totalRead,caracter;
char buffer[128] = {};
String entrada;

  if(MyRobot._Autonomo) MyRobot.Autonomo();

  //  **********Wifi
  if ((length = wifi.available()) > 0) {
       id = wifi.getId();
       caracter=wifi.read();  //lee caracter esperando comando $
       if (length > 0 && caracter=='$') {

           caracter=wifi.read();
           switch(caracter) {
               case'V':
               totalRead = wifi.readLine(buffer, 10);             // Cambia velocidad
               entrada=buffer;
                  MyRobot.SetVel((entrada.toInt()-90)/5+90);
              break;
               case'D':
               totalRead = wifi.readLine(buffer, 10);             // Cambia direccion
               entrada=buffer;
               MyRobot.SetDireccion((entrada.toInt()-90)/10+90);
                 break;
              
               case 'C':
               totalRead = wifi.readLine(buffer, 10);             // Comando
               entrada=buffer;
               comando=entrada.toInt();
               switch(comando){
                   case 0: //AVance continuo
                      if (MyRobot.EnMarcha()) MyRobot.Stop();
                      else   MyRobot.Move();
                   break;
                   case 1: //Mueve 10
                    MyRobot.Move(Av,10);
                   break;
                   case 2://Ret 10
                      MyRobot.Move(Rt,10);
                   break;
                   case 3: //GIRA  10º der
                    MyRobot.Giro(Dr,0,25);
                   break;
                   case 4: //-Gira 10 izq
                     MyRobot.Giro(Iz,,25);
                   break;
                   case 5: //GIRA 90º der
                   MyRobot.Giro(Dr,0,90);
                   break;
                   case 6: //Gira 90 izq
              MyRobot.Giro(Iz,90);
                   break;
                   case 10:
                    if(MyRobot._Autonomo) MyRobot._Autonomo=false;
                    else MyRobot._Autonomo=true;
                   break;
               }
              
               break;
              
           }
       }
   }

 
 }


void setup_wifi(){
    wifi.begin();
    wifi.setTimeout(2000);
    delay(2000);
    /****************************************/
    /******        WiFi commands       ******/
    /****************************************/
    // setWifiMode
   

//     wifi.setMode(ESP8266_WIFI_ACCESSPOINT);
//     wifi.setAPConfiguration("ESP8266", "awesomelib", 10, ESP8266_ENCRYPTION_WPA_WPA2_PSK);
//     wifi.restart();

    //Serial.println("Conectando Wifi");
    wifi.setMode(ESP8266_WIFI_STATION);



    if(!getStatus(wifi.joinAP(SSID, PASSWORD)))
                       Serial.println("Error al conectar al router");
                      

   
    // setMultipleConnections
    wifi.setMultipleConnections(true);

   
    // createServer
    //Serial.println("Creando servidor Telnet");
    wifi.createServer(23);
    }
   
    String getStatus(bool status)
    {
        if (status)
        return "OK";

        return "KO";
    }

    String getStatus(ESP8266CommandStatus status)
    {
        switch (status) {
            case ESP8266_COMMAND_INVALID:
            return "INVALID";
            break;

            case ESP8266_COMMAND_TIMEOUT:
            return "TIMEOUT";
            break;

            case ESP8266_COMMAND_OK:
            return "OK";
            break;

            case ESP8266_COMMAND_NO_CHANGE:
            return "NO CHANGE";
            break;

            case ESP8266_COMMAND_ERROR:
            return "ERROR";
            break;

            case ESP8266_COMMAND_NO_LINK:
            return "NO LINK";
            break;

            case ESP8266_COMMAND_TOO_LONG:
            return "TOO LONG";
            break;

            case ESP8266_COMMAND_FAIL:
            return "FAIL";
            break;

            default:
            return "UNKNOWN COMMAND STATUS";
            break;
        }
    }



Clase Robot
   Cabecera clase
 // ***********************************************
// Clase Robot
// Por Jos� Angel Moneo
// Gestiona el Robot creado por m�-
// LLeva dos ruedas mediante servos continuos
// Dos sensores de distancia ultras�nicos, uno adelante y oro atras
// Un sensor de audio
// Un m�dulo ESP8266 wifi
// No necesitaremos calibrado de motores, pues cada motor se calibra independientemente al ser servos
// ****************************************************








#ifndef Robot_h
#define Robot_h



#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif



#include <Servo.h>
#include <Ultrasonic.h>


//ServoMotores
#define MotorI  4
#define MotorD  5


#define Av 1
#define Rt 0
#define Iz 0
#define Dr 1


//ULTRASONIDOS
#define TRIGGER_PIND  6
#define TRIGGER_PINI  7
#define ECHO_PIND     8
#define ECHO_PINI     9



#define sonido A7



//D2 y D3 reservadas para encoder
//Reservadas SPI 10,11,12,13
//Reservadas I2C A4-A5
//Reservada Analogicas A7
//Libres Generales 5,6,A0,A1,A2,A3







class Robot
{   public:

        int PosMI,PosMD;  //posiciones de los motores
        boolean _Autonomo;
     private:
       int _VD,_VI;
     int _Velocidad;    //Velocidad del robot
     int _Direccion;
     int _Nataques; //cuenta ataques
      double cntEncoderD;
      double cntEncoderI;
     boolean _Marcha;
        boolean Marcha; //Robot en marcha
     //Servos
      Servo _MotorI;
      Servo _MotorD;

      //Ultrasonicos
       Ultrasonic *ultrasonicI;
       Ultrasonic *ultrasonicD;

    public:
        Robot();
    void Init();

        void SetVel(int Vel){_Velocidad=Vel; Move();}
        void SetDireccion(int direccion){_Direccion=direccion;Move();}  //Ajuste relacci�n potencias para determinar direcci�n 50 recto
        void Giro(boolean sent,int dist,int angulo);
        void Move();
        void Move(boolean sent,int Dist); //Mueve los servos hasta una posici�n
        void Stop();
        boolean EnMarcha(){return _Marcha;}  // test estado robot

// sensores de distancia
        int DistFront(boolean medicion);
        int DistBack(boolean medicion);
        void  Huida();
        void Autonomo();
      
    private:
       void  Amenaza(int v);
       int MinDist();
      void msg(String m,int val);
};


#endif




Funciones clase

#include "Robot.h"
#include <Servo.h>
#include <Ultrasonic.h>




Robot::Robot(){
    ultrasonicI=new Ultrasonic(TRIGGER_PINI, ECHO_PINI);
    ultrasonicD=new Ultrasonic(TRIGGER_PIND, ECHO_PIND);

    };



void Robot::Init(){
    pinMode(MotorI, OUTPUT);
    pinMode(MotorD, OUTPUT);
    _MotorI.attach(MotorI);
    _MotorD.attach(MotorD);
    _VD=_VI=_Velocidad=_Direccion=90;
    _Marcha=false;
    // inicialización compas
    Wire.begin();
    Stop();
   
   
}


void Robot::Move()
{  //Da orden de velocidades para movimiento conituno
    if(_Direccion>90) //Direccion a derecha
      {
          _VD=_Velocidad;
           if (_Velocidad<90)  _VI=90-(90-_Velocidad)/(_Direccion-90);
           else _VI=(_Velocidad-90)/(_Direccion-90)+90;
      }
     
     if(_Direccion<90) //Dirección a Izquierda
         {
             _VI=_Velocidad;
            if (_Velocidad<90)  _VD=90-(90-_Velocidad)/(90-_Direccion);
            else _VD=(_Velocidad-90)/(90-_Direccion)+90;
           
         }
      if(_Direccion==90)
      {
             _VI=_Velocidad; _VD=_Velocidad;
      }
    _MotorI.write(180-_VI); _MotorD.write(_VD);
    //ShowParam();
    _Marcha=true;
}

void Robot::Move(boolean sent,int Dist)
{  //invertimos el sentido si es necesario
    if (sent==Av) _VI=_VD=abs(_Velocidad-90)+90;
    if (sent==Rt) _VI=_VD=90-abs(_Velocidad-90);
    _MotorI.write(180-_VI); _MotorD.write(_VD);
    delay(Dist*10);
    Stop();
    _Marcha=false;   
}

void Robot::Stop()
{_MotorD.write(90);
_MotorI.write(90);   
_Marcha=false;
   
}


void Robot::Giro(boolean sent,int angulo)
{

    if (sent==Dr) _VI=_VD=abs(_Velocidad-90)/2+1+90;
    if (sent==Iz) _VI=_VD=90-abs(_Velocidad-90)/2-1;

_MotorI.write(_VI); _MotorD.write(_VD);

  }

  delay(angulo*10); 

  Stop();

   
}


///Sensores Distancia

int Robot::DistFront(boolean medicion)
{  float Dist;
    int av,i;
   
    if (medicion==1)
    {Dist=0;
        for(i=1;i<2;i++) Dist+= ultrasonicD->convert(ultrasonicD->timing(), Ultrasonic::CM);

    return Dist/2;}
    else
    Dist = ultrasonicD->convert(ultrasonicD->timing(), Ultrasonic::CM);


    av=(int)Dist;
    if (av<10) av=0;
    if (av>35) av=35;
    if (av!=0) av-=5;
    return av;
}


int Robot::DistBack(boolean medicion)
{  float Dist;
    int av,i;

    if (medicion==1)
    {Dist=0;
        for(i=1;i<4;i++)    Dist+= ultrasonicI->convert(ultrasonicI->timing(), Ultrasonic::CM);

    return Dist/2;}
    else
    Dist = ultrasonicI->convert(ultrasonicI->timing(), Ultrasonic::CM);
   

    av=(int)Dist;
    if (av<10) av=0;
    if (av>35) av=35;
    if (av!=0) av-=5;
    return av;
}

int Robot::MinDist()
{int i,d,maximo;

    // Busquea distancia minima
    maximo=DistFront(1);

    for (i=0;i<10;i++)
    {
        Giro(1,30);
        if ((d=DistFront(1))<maximo) maximo=d;
        if ((d=DistFront(1))<maximo) maximo=d;
       
    }
    return maximo;
}

void Robot::Huida()
{int d,dd;
   
        //msg("inicio huida ",0);
        //prueba de huida. 10 veces
        //Ataque por detras
        //msg("Espera acoso ",0);
        if(DistBack(1)<10) {_Nataques++;
                 SetVel(95);
                 SetDireccion(89);
            //SE ALEJA,manteniendose a 30 cm
            while ((d=DistBack(1))<10)
            { if((dd=DistFront(1))<20)  {Giro(Dr,90);/* msg("Gira 90 ",dd);*/ } //Giro 90º si no tengo espacio delante
            Move(Av,30);
            // msg("Avanza ",30-d);
        }
        if (_Nataques==5) Amenaza(0);
        }
        //Ataque por delante
        if(DistFront(0)<10){ _Nataques++;
                 SetVel(95);
                 SetDireccion(89);
            //SE ALEJA,manteniendose a 30 cm
            while ((d=DistFront(1))<10)
            { if((dd=DistBack(1))<20)  {Giro(Iz,90);/* msg("Gira 90 ",dd);*/ } //Giro 90º si no tengo espacio delante
            Move(Rt,30);
            //msg("Retrocede ",30-d);
        }
        if (_Nataques==5) Amenaza(1);
         }

   
   
   

}


void Robot::Amenaza(int v)
{int i,d,dd;
    SetVel(120);
    //por detras
        if(v==0) {   
           
        Giro(Dr,90);
        Giro(Dr,90);
        // msg("Caballo loco",0);
        //Caballo loco
        for(i=0;i<5;i++){
            Move(Av,15);
            Move(Rt,15);
            _Nataques=0;
        }
    }
    // por delante
    if(v==1) {
        // msg("Caballo loco",0);
        //Caballo loco
        for(i=0;i<5;i++){
            Move(Av,15);
            Move(Rt,15);
            _Nataques=0;
        }
    }
   
}



void Robot::Autonomo()
{ int d;
     SetVel(95);
     SetDireccion(88);
   
    //Recorrido autonomo
    // msg("Programa Autonomo ",0);
    //Busqueda pared
    while ((d=DistFront(1))>10)   Move(Av,d);
   
    while ((d=DistFront(1))<11) Giro(Dr,45);
   
}

void Robot::msg(String m,int val)
{ Serial.print(m);
  Serial.println(val);
  }


MainActivity de Android
package com.example.joseangel.Robot;

import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.TextView;
import android.view.View;
import android.widget.ImageView;


public class MainActivity extends ActionBarActivity {
    private Button btconect, btdisconect, btsndtxt, btnizq, btnder, bt0, bt1,
            bt2,bt3,bt4,bt5,bt6,bt10;
    private SeekBar vel,dir;
    private TextView txtstatus;
    private EditText ipinput, portinput, input_txt;
    private ImageView leds;
    private boolean connected = false;
    private Socket socket;
    private String serverIpAddress = "192.168.1.17";
    private static final int REDIRECTED_SERVERPORT = 23;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        leds = (ImageView) findViewById(R.id.leds);
        btconect = (Button) findViewById(R.id.btcnt);
        btdisconect = (Button) findViewById(R.id.btdisc);
        bt0 = (Button) findViewById(R.id.bt0);
        bt1 = (Button) findViewById(R.id.bt1);
        bt2 = (Button) findViewById(R.id.bt2);
        bt3 = (Button) findViewById(R.id.bt3);
        bt4 = (Button) findViewById(R.id.bt4);
        bt5 = (Button) findViewById(R.id.bt5);
        bt6 = (Button) findViewById(R.id.bt6);
        bt10 = (Button) findViewById(R.id.bt10);
        txtstatus = (TextView) findViewById(R.id.txtstatus);
        vel = (SeekBar) findViewById(R.id.Posicion);
        dir = (SeekBar) findViewById(R.id.Direcc);

        vel.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                                          boolean fromUser) {
                // TODO Auto-generated method stub
                String msg;
                msg=String.valueOf(progress);  // o Integer.toString(pos_bar):
                boolean val_acc = Snd_Msg("$V"+msg);
                //error al enviar
                if (!val_acc) {
                    Set_txtstatus(" Error  ", 0);
                    Change_leds(false);
                    Log.e("Snd_Action() -> ", "!ERROR!");

                }

                if (!socket.isConnected())
                    Change_leds(false);

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub
            }
        });
       dir.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                                          boolean fromUser) {
                // TODO Auto-generated method stub
                String msg;
                msg=String.valueOf(progress);  // o Integer.toString(pos_bar):
                boolean val_acc = Snd_Msg("$D"+msg);
                //error al enviar
                if (!val_acc) {
                    Set_txtstatus(" Error  ", 0);
                    Change_leds(false);
                    Log.e("Snd_Action() -> ", "!ERROR!");

                }

                if (!socket.isConnected())
                    Change_leds(false);

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub
            }
        });
        //Botones de Accion
        bt0.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Snd_Action(0);
            }
        });

        bt1.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Snd_Action(1);
            }
        });

        bt2.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Snd_Action(2);
            }
        });

        bt3.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Snd_Action(3);
            }
        });
        bt4.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Snd_Action(4);
            }
        });

        bt5.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Snd_Action(5);
            }
        });

        bt6.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Snd_Action(6);
            }
        });

        bt10.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Snd_Action(10);
            }
        });


        //Al clickear en conectar
        btconect.setOnClickListener(new OnClickListener() {
            @Override
            // conectar
            public void onClick(View v) {
                //Nos conectamos y obtenemos el estado de la conexion
                boolean conectstatus = Connect();
                //si nos pudimos conectar
                if (conectstatus) {//mostramos mensaje
                    Set_txtstatus("Conexion OK ", 1);
                    Change_leds(true);//camiamos img a verde

                } else {//error al conectarse
                    Change_leds(false);//camiamos img a rojo
                    //mostramos msg de error
                    Set_txtstatus("Esconectado.. ", 0);
                }
            }
        });
        //Al clickear en desconectar
        btdisconect.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean conectstatus=Disconnect();
                if (conectstatus) {//mostramos mensaje
                    Set_txtstatus(".. En espera ..", 1);
                    Change_leds(false);//camiamos img a verde

                }
                else {//error al conectarse
                    Change_leds(false);//camiamos img a rojo
                    //mostramos msg de error
                    Set_txtstatus("Desconectado.. ", 0);
                }

            }
        });


    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    //Enviamos mensaje de accion segun el boton q presionamos
    public void Snd_Action(int bt) {
        String msg="";
        //no hay texto

        //seteo en el valor action el numero de accion
        switch (bt) {
            case 0:
                msg = "$C0";
                break;
            case 1:
                msg = "$C1";
                break;
            case 2:
                msg = "$C2";
                break;
            case 3:
                msg = "$C3";
                break;
            case 4:
                msg = "$C4";
                break;
            case 5:
                msg = "$C5";
                break;
            case 6:
                msg = "$C6";
                break;
            case 10:
                msg = "$C10";
                break;
        }
             //mando msg
        boolean val_acc = Snd_Msg(msg);
        //error al enviar
        if (!val_acc) {
            Set_txtstatus(" Error  ", 0);
            Change_leds(false);
            Log.e("Snd_Action() -> ", "!ERROR!");

        }

        if (!socket.isConnected())
            Change_leds(false);
    }


    /*Metodo para enviar mensaje por socket
     *recibe como parmetro un objeto Mensaje_data
     *retorna boolean segun si se pudo establecer o no la conexion
     */
    public boolean Snd_Msg(String msg) {
        try {
            //Accedo a flujo de salida
            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
            if (socket.isConnected())// si la conexion continua
            {
                //Envio mensaje por flujo
                out.println(msg);
                //envio ok
                return true;
            } else {//en caso de que no halla conexion al enviar el msg
                Set_txtstatus("Error...", 0);//error
                return false;
            }

        } catch (IOException e) {// hubo algun error
            Log.e("Snd_Msg() ERROR -> ", "" + e);
            return false;
        }
    }


    //cambia el imageview segun status
    public void Change_leds(boolean status) {
       if (status)
           leds.setImageResource(R.drawable.on);
        else
           leds.setImageResource(R.drawable.off);
    }

    /*Cambiamos texto de txtstatus segun parametro flag_status
     * flag_status 0 error, 1 ok*/
    public void Set_txtstatus(String txt, int flag_status) {
        // cambiel color
        switch (flag_status){
        case 0:
            txtstatus.setTextColor(Color.RED);
             break;
        case 1:
            txtstatus.setTextColor(Color.GREEN);
            break;
        case 2:
            txtstatus.setTextColor(Color.BLACK);
            break;
        }
        txtstatus.setText(txt);
    }

    //Conectamos
    public boolean Connect() {
        //Obtengo datos ingresados en campos
        try {
            InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
            socket = new Socket(serverAddr, REDIRECTED_SERVERPORT);
            //si nos conectamos
            if (socket.isConnected() == true) {
                return true;
            } else {
                return false;
            }
        } catch (UnknownHostException e1) {
            e1.printStackTrace();
            //Si hubo algun error mostrmos error
            txtstatus.setTextColor(Color.RED);
            txtstatus.setText(" !!! ERROR  !!!");
            Log.e("Error connect()","");
            return false;
        } catch (IOException e1) {
            e1.printStackTrace();
            //Si hubo algun error mostrmos error
            txtstatus.setTextColor(Color.RED);
            txtstatus.setText(" !!! ERROR  !!!");
            Log.e("Error connect()","");
            return false;

        }

    }

    //Metodo de desconexion
    public boolean Disconnect() {

        //Prepramos mensaje de desconexion
        //avisamos al server que cierre el canal
        try {
        socket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
        if (socket.isConnected())
             return false;
        return true;
    }

}