domingo, 29 de diciembre de 2013

ArduinoBluetoothCar controlado con aplicación Android desde el móvil

Prueba de comunicación entre Arduino y un teléfono Android con una aplicación hecha con AppInventor

Me he basado en  http://www.instructables.com/id/How-control-arduino-board-using-an-android-phone-a/
La conexión física de la tarjeta bluetooth con el arduino la he tomado de: http://www.instructables.com/id/Cheap-2-Way-Bluetooth-Connection-Between-Arduino-a/?ALLSTEPS
y de http://www.instructables.com/id/Androino-Talk-with-an-Arduino-from-your-Android-d/?ALLSTEPS

Versión v1: Mediante botones en el teléfono controlo el coche
Versión v2: Añado control por movimiento del teléfono sin necesidad de pulsar botones
Versión v3: Añado control por voz y sensor de distancia

IMPORTANTE: Para evitar el error avrdude: stk500_getsync(): not in sync: resp=0x00 cuando se sube el programa al arduino hay que desconectar el cable que va al pin 0 (RX): "DISCONNECT ANY WIRES going to pin 0 (RX) while you do the upload. The sketch upload function uses the RX pin".

El código Android está programado con la versión 1 de appinventor.mit.edu

Sincronización
Control por teclado
Control por voz
Control por gestos
Código de la aplicación desarrollada con appInventor para el teléfono:


Código fuente del Arduino:


//Prueba de comunicación entre Arduino y un teléfono Android con una aplicación hecha con AppInventor
// Tomado de http://www.instructables.com/id/How-control-arduino-board-using-an-android-phone-a/
// la conexión física de la tarjeta bluetooth con el arduino la he tomado de:
// http://www.instructables.com/id/Cheap-2-Way-Bluetooth-Connection-Between-Arduino-a/?ALLSTEPS
// y de http://www.instructables.com/id/Androino-Talk-with-an-Arduino-from-your-Android-d/?ALLSTEPS
// Versión v1: Mediante botones en el teléfono controlo el coche
// Versión v2: Añado control por movimiento del teléfono sin necesidad de pulsar botones
// Versión v3: Añado sensor de distancia

// IMPORTANTE: Para evitar el error avrdude: stk500_getsync(): not in sync: resp=0x00 cuando se sube el programa al arduino hay que
// DISCONNECT ANY WIRES going to pin 0 (RX) while you do the upload. The sketch upload function uses the RX pin. 

#include 

AF_DCMotor motor1(1, MOTOR12_64KHZ);
AF_DCMotor motor2(2, MOTOR12_64KHZ);

const uint8_t SPEED_INCREMENT = 50;
byte serialA;

uint8_t speed = 255;

uint8_t distanceStatus=1; //1 Far, 2 Middle, 3 Near
//uint8_t oldDistanceStatus=1;
//uint8_t greenDistance=100;
int yellowDistance=250;
int redDistance=530;

int distanceSensorPin = A0;
int distanceSensorValue;

int read1, read2, read3, readMedia, readDiference1, readDiference2, readDiference3;
const int TOLERABLE_READ_ERROR = 30;

void setup()
{
  // initialize the serial communication:
  Serial.begin(9600); //baud rate - make sure it matches that of the module you got:
  
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  }

void loop() {
  if (Serial.available() > 0) {
    serialA = Serial.read();
//    Serial.println(serialA);
    processCommand(serialA);
  }
  processDistance();
}

void processCommand(byte command){
  switch (command) {
  case 1:
//    Serial.println("********Recived 1 *******");
    left();
    break;
  case 2:
//    Serial.println("********Recived 2 *******");
    right();
    break;
  case 3:
//    Serial.println("********Recived 3 *******");
    forward();
    break;
  case 4:
//    Serial.println("********Recived 4 *******");
    backward();
    break;
  case 5:
//    Serial.println("********Recived 5 *******");
    fullStop();
    break;   
  case 6:
//    Serial.println("********Recived 6 *******");
    increaseSpeed();
    break;  
  case 7:
//    Serial.println("********Recived 7 *******");
    decreaseSpeed();
    break;      
  default:
//    Serial.print("********Recived unexpected command: ") + Serial.println(command);
    break;
  }
}

void right(){
//  Serial.println("Turning right...");
  motor1.run(FORWARD);
  motor1.setSpeed(speed);
  motor2.run(RELEASE);
}

void left(){
//  Serial.println("Turning left...");
  motor2.run(FORWARD);
  motor2.setSpeed(speed);
  motor1.run(RELEASE);
}

void forward(){
//  Serial.println("Forward...");
  motor1.run(FORWARD);
  motor2.run(FORWARD);  
  motor1.setSpeed(speed);
  motor2.setSpeed(speed);
}

void backward(){
//  Serial.println("Backward...");
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);  
  motor1.setSpeed(speed);
  motor2.setSpeed(speed);
}

void fullStop(){
//  Serial.println("FullStop...");  
  motor1.run(RELEASE);
  motor2.run(RELEASE);  
}

void increaseSpeed(){
//  Serial.println("IncreaseSpeed...");  
  if ((speed + SPEED_INCREMENT) > 255){
    speed = 255;
  }else{
    speed += SPEED_INCREMENT;
  }
  motor1.setSpeed(speed);
  motor2.setSpeed(speed);
}

void decreaseSpeed(){
//  Serial.println("DecreaseSpeed...");    
  if ((speed - SPEED_INCREMENT) < 0){
    speed = 0;
  }else{
    speed -= SPEED_INCREMENT;
  }
  motor1.setSpeed(speed);
  motor2.setSpeed(speed);
}

void processDistance(){
   // read the value from the sensor:
  distanceSensorValue = readDistance();
  
//  Serial.print("distanceSensorValue=");
//  Serial.println(distanceSensorValue);
  
//  Serial.print("distanceStatus=");
//  Serial.println(distanceStatus);
  
  if (distanceSensorValue == 999){
    //error in read
    return;
  }
  
  if (distanceSensorValue < yellowDistance && distanceStatus != 1){
//   Serial.println("distanceStatus_1"); 
   distanceStatus=1; 
   Serial.print("1"); //Sending to phone
  }else if (distanceSensorValue >= yellowDistance && distanceSensorValue < redDistance && distanceStatus != 2){
//   Serial.println("distanceStatus_2");   
   distanceStatus=2; 
   Serial.print("2"); //Sending to phone
  }else if (distanceSensorValue >= redDistance && distanceStatus != 3){
//   Serial.println("distanceStatus_3");
   distanceStatus=3; 
   Serial.print("3"); //Sending to phone
   fullStop();
  }
}

// return media of to 3 reads  or 999 if there is error
int readDistance(){
    read1=analogRead(distanceSensorPin);
    delay(50); //delay between readings to avoid errors because of erratic reading
    read2=analogRead(distanceSensorPin);
    delay(50); //delay between readings to avoid errors because of erratic reading
    read3=analogRead(distanceSensorPin);
    delay(50);

    readMedia = (read1 + read2 + read3)/3;
    
    //we need to use readDiferenceX variables due to abs() limitations (read Reference Documentation)
    readDiference1 = read1 - readMedia;
    readDiference2 = read2 - readMedia;
    readDiference3 = read3 - readMedia;
    
    if ((abs(readDiference1) > TOLERABLE_READ_ERROR) || (abs(readDiference2) > TOLERABLE_READ_ERROR) || (abs(readDiference2) > TOLERABLE_READ_ERROR)){
      // the 3 reads have too many differences
      return 999;
    }
    return (read1 + read2 + read3)/3; //media of the 3 reads
}


No hay comentarios:

Publicar un comentario