Auto bluetooth con 4 sensores de distancia y i2c

Master

#include "Wire.h"
#include <SoftwareSerial.h>       
SoftwareSerial BTSerial(12,13);

uint8_t I2C_SLAVE_ADDR =0x01;

const bool ResetInError=1;

const int Key_Cambiar_Modo = 1;
const int Key_Confirmar_Modo = 2;
const int Key_Agregar_Modo = 3;
const int Key_Confirmar_Variable=0;
const int Key_Arduino_Ocupado=255;

const String Arduino_Start_1 = "Canal Serial Abierto :)";
      String Arduino_Start_2 = "Canal Bluetooth Abierto :)";
const String Arduino_Start_3 = "Canal Wire Abierto :)";
const String Arduino_Start_4 = "Arduino Maesto Iniciado";

const String Arduino_OnRecive = "Recibido : ";
const String Arduino_MovimientoIniciado = "Movimiento Iniciado : ";
const String Arduino_MovimientoTerminado = "Apagando Movimiento";

const String Arduino_ERR_1 = "Err 1 : Algo salio mal cambiando el modo del arduino";
String Arduino_ERR_2 = "Err 2 : Algo salio mal agregando un modo al esclavo";

int Codigos_de_Movimiento[7][12]={
	  {0,0,0,0,0,0,0,0,1,10,-1,1},
      {1,0,1,0,0,1,0,1,4,5000,0,20},
      {0,1,0,1,1,0,1,0,6,5000,1,20},
      {0,1,0,1,0,1,0,1,8,5000,255,23},
      {1,0,1,0,1,0,1,0,10,5000,255,23},
      {1,0,1,0,0,1,0,1,12,5000,2,20},
      {0,1,0,1,1,0,1,0,14,5000,3,20}
};

uint8_t Motor_Num[8]={2,6,10,11,A0,A1,A2,A3};
uint8_t acutal_Motor_Modes[4]={0,0,0,0};
uint8_t Mode=0;

void setup(){
  
  if(ResetInError){Arduino_ERR_2+="\nEl esclavo se Reiniciara";}
  long t1 = millis();
  
  
  for(int i = 0;i<8;i++){pinMode(Motor_Num[i],OUTPUT);}
  Wire.begin();
  Serial.begin(9600);
	
  BTSerial.begin(9600);
  BTSerial.println(1);
  
  while(true){
    if(Iniciar()){break;}
            
  }
  
}
int asd =0;
void loop(){
 
  if(Serial.available()>0){
  	int e =(Serial.read());
    Mode = e - 48;
    Serial.println(Mode);
      CambiarMovimiento(Mode); 
  }
}

void CambiarMovimiento(uint8_t codigo){
	//Cambiar Movimiento, Osea salir del estado de reposo a X movimiento 
  	//realizar todo su tiempo y movimiento hasta que se termine o tenga algo delante
  	//al finaliar detiene todo y vuelve a reposo
  
  if(Iniciar_Movimiento(codigo)){
  	//Si logra iniciar correctamente el movimiento
    long t1 = millis();//Tiempo en el que se inicio el movimiento
    int delta=0;//No hace falta explicar lo que delta tiempo significa
    uint8_t distancia =0;
    while(delta<Codigos_de_Movimiento[codigo][9]){
    	//Mientras el delta tiempo sea menor que el tiempo de ejecucion del movimeinto hace este loop
      if(Codigos_de_Movimiento[codigo][10]==-1){
      	//Si no usa ningun sensor
      	//No hace nada
      }else{
      	//Si usa algun sensor conectado
        distancia= PedirDatos();
        //Pedir la distancia reportada por el sensor
        Serial.println("dis = "+String(distancia));
        byte distancia1 = (distancia>>(codigo-1))&0b00000001;
        
        if(distancia1 == 0){
          //Si la distancia es menor que el minimo permitido
          delay(50);
          digitalWrite(11,0);  
          break;
        }else{
          digitalWrite(11,1);  
        }
        long t2 = millis();
      	delta = t2-t1;
      }
    }digitalWrite(11,0);
    if(asd>1){
      asd--;
      distancia = distancia | 0b00000001;
    } 
    Serial.write(asd); 
    ApagarTodo();
    
  }else{
  	//Si algo sale
  }
}


bool Iniciar_Movimiento(uint8_t codigo){
  //Valga la redundancia Este metodo inicia un movimiento
  //Devuelve true si el movivimiento se inicio correctamente
  //Devuelve false si algo sale mal
  
  if(CambiarModo(Codigos_de_Movimiento[codigo][8]/*Cambia modo del esclavo*/)){
    //Iniciar motor 1, si algo falla devuelve falso y apaga todo
    if(!Motor(1,Codigos_de_Movimiento[codigo][0],Codigos_de_Movimiento[codigo][1])){ApagarTodo();return false;}
    //Iniciar motor 2, si algo falla devuelve falso y apaga todo
    if(!Motor(2,Codigos_de_Movimiento[codigo][2],Codigos_de_Movimiento[codigo][3])){ApagarTodo();return false;}
    //Iniciar motor 3, si algo falla devuelve falso y apaga todo
    if(!Motor(3,Codigos_de_Movimiento[codigo][4],Codigos_de_Movimiento[codigo][5])){ApagarTodo();return false;}
    //Iniciar motor 4, si algo falla devuelve falso y apaga todo
    if(!Motor(4,Codigos_de_Movimiento[codigo][6],Codigos_de_Movimiento[codigo][7])){ApagarTodo();return false;}
    
    Mode=codigo;
    return true;
    
  }else{
  	return false;
  }
}
byte PedirDatos(){
	Send_To_Slave(Key_Confirmar_Variable);
  //byte res=Obtener_Respuesta(0);
  //if(res=Key_Arduino_Ocupado)return 1;
  //else return res;
  return Obtener_Respuesta(0);
}

bool CambiarModo(uint8_t Codigo){
  Send_To_Slave(Key_Confirmar_Modo,10);
  //Pide confirmacion en que modo esta el esclvo
  if(Obtener_Respuesta(0)!=Codigo){
    //Si no esta en el modo que se necesita
    Send_To_Slave(Key_Cambiar_Modo,Codigo);
    //Cambia el modo del esclavo
    Send_To_Slave(Key_Confirmar_Modo,10);
    //Pide confirmacion de en que modo esta el esclvo
    
    //1er intento
    if(Obtener_Respuesta(0)!=Codigo){
      //Si no esta en el modo que se necesita
      Send_To_Slave(Key_Cambiar_Modo,Codigo);
      //Cambia el modo del esclavo
      Send_To_Slave(Key_Confirmar_Modo,10);
      //Pide confirmacion de en que modo esta el esclvo
      
      //2do intento
      if(Obtener_Respuesta(0)!=Codigo){
        //Si no esta en el modo que se necesita
   	    Send_To_Slave(Key_Cambiar_Modo,Codigo);
        //Cambia el modo del esclavo
        Send_To_Slave(Key_Confirmar_Modo,10);
        if(Obtener_Respuesta(0)==Codigo){
          return true;
        }
      }else{
      	return true;
      }
    }else{
      return true;
    }
  }else{
    return true;
  }
  /////////////
  Serial.println(Arduino_ERR_1);
  return false;
}

void ApagarTodo(){
  CambiarModo(1);
  //Cambia el esclavo a modo reposo
  
  for(int i = 0;i<8;i++){
    digitalWrite(Motor_Num[i],false);
  	//apaga todos los motores
  }
  for(int i =0;i<4;i++){
    acutal_Motor_Modes[i]=0;
    //apaga las referencias de los motores en esta variable
  }
  Serial.println(Arduino_MovimientoTerminado);
  Mode=0;
}
bool Motor(uint8_t motor,uint8_t a,uint8_t b){
  byte c=a|b<<1;
  switch(c){
  	case 3:return false;
    default:acutal_Motor_Modes[motor]=c;
  }
  switch(motor){
    default:return false;
  	case 1:digitalWrite(Motor_Num[0],a);digitalWrite(Motor_Num[1],b);break;
    case 2:digitalWrite(Motor_Num[2],a);digitalWrite(Motor_Num[3],b);break;
    case 3:digitalWrite(Motor_Num[4],a);digitalWrite(Motor_Num[5],b);break;
    case 4:digitalWrite(Motor_Num[6],a);digitalWrite(Motor_Num[7],b);break;
  }
  return true;
}
bool Iniciar(){
  ApagarTodo();
  //Apaga todo para iniciar
  
  for(int i =1; i<(sizeof(Codigos_de_Movimiento)/sizeof(Codigos_de_Movimiento[0]));i++){
    //Agrega todos los modos al esclavo

    if(!AgregarModo(i-1,Codigos_de_Movimiento[i][8],Codigos_de_Movimiento[i][10],Codigos_de_Movimiento[i][11],true)){return false;}
  }
  
  //si todo se agredo retorna true
  return true;
}
byte recivedData[5];
bool AgregarModo(int pos,int a, int b, int c,bool master){
  Serial.println("Intentando agregar "+String(pos)+" "+String(a)+" "+String(b)+" "+String(c));
  Send_To_Slave(Key_Agregar_Modo,pos,a,b,c);
  //Manda a agregar el modo a, con el valor b y el sensor c en la posicion pos
  Send_To_Slave(Key_Confirmar_Modo,pos);
  //Pide la confirmacion del modo guardado en la posicion pos
  
  Obtener_Respuesta(2);
  
  //Obtenemos los valores del metodo guardado en la posicion pos
  if(master){
    for(int i = 0 ; i<3;i++){
      //El metodo se llamara a si mismo 3 veces, pero las 3 repeticiones no tienen permiso
      //De llamar 3 veces a si misma porque generarian un bucle infinito y no gracias
      if(AgregarModo(pos,a,b,c,0)){return true;}
    }
    //Si sale del for y llega hasta aca significa que los 3 intentos fallaron
    //Antes de retornar falso reinicia el arduino esclavo si la variable ResetInError es true
    if(ResetInError){
    	Send_To_Slave(Key_Cambiar_Modo,0);
      	EsperarQueReviva();
    }
    
    return false;
  }else{
    if(recivedData[0] ==a&&recivedData[1] ==b){
      return true;
    }else{
      return false;
    }
  }
}
bool EsperarQueReviva(){
  while(!Wire.available()){
  	Obtener_Respuesta(0);
  }
  Wire.read();
}


uint32_t Obtener_Respuesta(int t1){
  switch(t1){
    case 0 :{
    uint8_t response;
      
      Wire.requestFrom(I2C_SLAVE_ADDR, sizeof(response));
      long t = millis();
      while(Wire.available() < 1){
        long delta = millis()-t;
        if(delta>500){
          return 0;
        }
      }
      for(int i = 0;i<((8*t1)+1);i+=8){
  	    response =response +( Wire.read()<<i);
      }
      //Serial.println("res "+response); 
  	  return response;
     
    }
    case 1:{
    uint16_t response;
      Serial.println(sizeof(response));
      Wire.requestFrom(I2C_SLAVE_ADDR, sizeof(response));
      long t = millis();
      while(Wire.available() < 1){
        long delta = millis()-t;
        if(delta>500){
          return 0;
        }
      }
      for(int i = 0;i<((8*t1)+1);i+=8){
  	    response =response |( Wire.read()<<i);
      }
  	  return response;
    }
    case 2:{
    uint32_t response;
      
      Wire.requestFrom(I2C_SLAVE_ADDR, sizeof(response));
      long t = millis();
      while(Wire.available() < 1){
        long delta = millis()-t;
        if(delta>500){
          return 0;
        }
      }
      int i2 =0;
      for(int i1 = 0;i1<((8*(sizeof(response)))+1);i1 +=8){
  	    byte rr = Wire.read();
        recivedData[i2]=rr;
        i2++;
      }
  	  return response;
    }
    case 3:{
      uint32_t response;
      Serial.println(sizeof(response));
      Wire.requestFrom(I2C_SLAVE_ADDR, sizeof(response));
      long t = millis();
      while(Wire.available() < 1){
        long delta = millis()-t;
        if(delta>500){
          return 0;
        }
      }
      for(int i = 0;i<((8*t1)+1);i+=8){
  	    response =response |( Wire.read()<<i);
      }
  	  return response;
    }
  }
  
}
void Send_To_Slave(uint8_t data){
  Wire.beginTransmission(I2C_SLAVE_ADDR);
  Wire.write((byte*)&data, sizeof(data));
  Wire.endTransmission();
}
void Send_To_Slave(uint8_t data,uint8_t data1){
  Wire.beginTransmission(I2C_SLAVE_ADDR);
  Wire.write((byte*)&data, sizeof(data));
  Wire.write((byte*)&data1, sizeof(data1));
  Wire.endTransmission();
}
void Send_To_Slave(uint8_t data,uint8_t data1,uint8_t data2){
  Wire.beginTransmission(I2C_SLAVE_ADDR);
  Wire.write((byte*)&data, sizeof(data));
  Wire.write((byte*)&data1, sizeof(data1));
  Wire.write((byte*)&data2, sizeof(data2));
  Wire.endTransmission();
}
void Send_To_Slave(uint8_t data,uint8_t data1,uint8_t data2,uint8_t data3){
  Wire.beginTransmission(I2C_SLAVE_ADDR);
  Wire.write((byte*)&data, sizeof(data));
  Wire.write((byte*)&data1, sizeof(data1));
  Wire.write((byte*)&data2, sizeof(data2));
  Wire.write((byte*)&data3, sizeof(data3));
  Wire.endTransmission();
}
void Send_To_Slave(uint8_t data,uint8_t data1,uint8_t data2,uint8_t data3,uint8_t data4){
  Wire.beginTransmission(I2C_SLAVE_ADDR);
  Wire.write((byte*)&data, sizeof(data));
  Wire.write((byte*)&data1, sizeof(data1));
  Wire.write((byte*)&data2, sizeof(data2));
  Wire.write((byte*)&data3, sizeof(data3));
  Wire.write((byte*)&data4, sizeof(data4));
  Wire.endTransmission();
}

Slave

#include "Wire.h" 

const int Error_code =0;

const String Advertencia_Sensor_Desconectado="Advertencia: Es posible que este un sensor desconectado";
const String Alerta_Sensor_Desconectado="Alerta: Es posible que tenga un sensor desconectado, mal conectado o los codigos esten cambiados\n  Conecte los sensores y reinicie el arduino.";
const int Key_Arduino_Ocupado=255;

volatile bool Cambiando_Modo=false;
volatile bool Agregando_Modo=false;

volatile int  Target=0;
bool Ocupado = false;

volatile int  keycode=0;

volatile int  variable=0;

volatile bool Pidiendo_Modo=false;
volatile int  Modo_Solicitado=0;
volatile bool Pidiendo_Modo_Val=false;


volatile byte Modos[7][4]={
  {2,0,40,1},
  {3,1,40,1},
  {4,2,40,1},
  {5,3,40,1},
  {6,3,40,1},
  {8,3,40,1},
  {9,3,40,1}
};
//********************************/

byte AccionSolicitada = 0;

bool Sensores_Conectados[4]={1,1,1,1};

int Sensor_Pines[4][3]={
  {5,4,6},//adelante
  {12,11,13},//atras
  {A0,A1,16},//izquierda
  {A2,A3,17}//derecha
};

volatile bool Error_Ocurred=false;

volatile byte Modo = 0;

bool Haciendo_Algo = 0;
bool Active = 1;


void setup() {
 	//CODIGO esclavo
  Serial.begin(9600);
  Serial.setTimeout(0);
  for(int i = 0;i<(4);i++){
    pinMode(Sensor_Pines[i][0],OUTPUT);
    pinMode(Sensor_Pines[i][1],INPUT);
    pinMode(Sensor_Pines[i][2],OUTPUT);
    digitalWrite(Sensor_Pines[i][2],1);
  }
    Serial.println("Se esta iniciando correctamente");
      Wire.begin(0x01); //identifico como esclavo 1
  	  Wire.onReceive( receiveEvent); //Declaro Evento
 	  Wire.onRequest(Peticion); //Declaro Evento
      Active=1;
}

void loop() {
  if(Wire.available()){receiveEvent(1);}
  if(Serial.available()){
    String a =Serial.readString();
    Serial.println(">"+a);
    if(a=="/getModes"){
        for(int ax = 0;ax<7;ax++){
        Serial.println("Modo "+String(ax)+" : "+String(Modos[ax][0]));
        }
    }else if(a=="/desconectar"){
        Modo=0;
    }
    else if(a=="/reiniciar"){
        for(int ax = 0;ax<7;ax++){
        Serial.println("Modo "+String(ax)+" : "+String(Modos[ax][0]));
        }
    }
  }
  if (Modo== 0){
    Serial.println("I am here");
    Reset();
  }else if(Modo==1){
    for (int t  = 0; t<4; t++) {
      for (int i = 0; i<7; i++) {
        AnalizarSensor(i);
      }
    }
    
    TestearSensores();

  }else if(Active){
    
  //  AnalizarSensor(Modo-2);
  }else{
    Error_Ocurred=1;
  }
  
}
byte AnalizarSensor(int s){
  Serial.println("Sp"+String(s)+","+String(Sensores_Conectados[ Modos[s][1]]));

  if(Modos[s][1]!=255){
    if(Sensores_Conectados[ Modos[s][1]]){
      byte sensor =0.01723 *Analizar(Sensor_Pines[Modos[s][1]][0],Sensor_Pines[Modos[s][1]][1]);
      Serial.println(String(Modos[s][2])+"<"+String(sensor));   
      if((sensor>Modos[s][2])){
        Modos[s][3]=1;
        return 1;
      }else{ 
        Modos[s][3]=0;
        return 0;
      }
     
    }else{
      
      Modos[s][3]=0;
      return 0;
    }
  }else{
    
    Modos[s][3]=1;
    return 1;
  }
  
}
bool TestearSensores(){
  for(int i = 0; i<4;i++){
    if(1){
      //Si el sensor no devuelve nada lo vuelve a intentar
      
      if(Analizar(Sensor_Pines[i][0],Sensor_Pines[i][1])<=0){
        //Si el sensor no devuelve nada lo vuelve a intentar
        
        //Serial.println("Intento 1 del senosor "+String(i+1)+" Fallido");
        if(Analizar(Sensor_Pines[i][0],Sensor_Pines[i][1])<=0){
          //Si el sensor no devuelve nada lo vuelve a intentar
          
          //Serial.println("Intento 2 del senosor "+String(i+1)+" Fallido");
          if(Analizar(Sensor_Pines[i][0],Sensor_Pines[i][1])<=0){
            //Cuando ocurren 3 fallos interpreta que el sensor esta desconectado
            //Si el arduino se esta ejecutando solamente muestra una advertencia en consola
            //Si se esta iniciando no le permite iniciarse
            
            //Serial.println("Intento 3 del senosor "+String(i+1)+" Fallido");
            
              //Serial.println(Advertencia_Sensor_Desconectado);
              Sensores_Conectados[i] = 0;
              digitalWrite(Sensor_Pines[i][2],0);
            

            }else{
              Sensores_Conectados[i] = 1;
              digitalWrite(Sensor_Pines[i][2],1);
            }
          }else{
            Sensores_Conectados[i] = 1;
            digitalWrite(Sensor_Pines[i][2],1);
          }
        }else{
         Sensores_Conectados[i] = 1;
   	     digitalWrite(Sensor_Pines[i][2],1);
      }
    
    }
    
            
  }
  return true;
}

void Reset(){
  Wire.endTransmission();
	Serial.println("Reset");/*
  Cambiando_Modo=false;
  Agregando_Modo=false;
  Target_Modo_seleccionado=false;
  Target=0;
  Modo_keycode_annadida=false;
  keycode=0;
  Modo_variable_val_annadido=false;
  variable=0;
  active=0;
  Pidiendo_Modo=false;
  Modo_Solicitado=0;
  Pidiendo_Modo_Val=false;   
  ModoAdelante_V=0;
  ModoAdelante[0]=0;
	ModoAdelante[1]=0;
  
  ModoAtras_V=0;
  ModoAtras[0]=0;
	ModoAtras[1]=0;

  ModoGirando_V=0;
  ModoGirando[0]=0;
  ModoGirando[1]=0;*/
  Modo =1;Wire.begin(0x01); //identifico como esclavo 1
 	Wire.onReceive(receiveEvent); //Declaro Evento
 	Wire.onRequest(Peticion); //Declaro Evento
}
void receiveEvent(int bytes){
  
  byte data[bytes];

  for(int i =0;i<bytes;i++){
  	data[i]=Wire.read();
  }
  byte AccionEnviada = data[0];
  switch(AccionEnviada){
    case 0:{//Pedir modo val
      AccionSolicitada=(1);
    }break;
    case 1:{//Cambiar Modo
      /*
        El error que esta ocurriendo no resuelto creo que es que el maestor
        esta mandando la posicion dentro del array, y el esclavo quiere recibir la key
        entonces no hace nada
        pero despues del escrito vemos 
        */
      byte ValorSecundario = data[1];//Valor real
      int i = 0;
      //Serial.println("se quiere cambiar a "+String(ValorSecundario));
      Serial.println("Se quiere cambiar a "+String(ValorSecundario));
      if(ValorSecundario<2){
      	Modo =ValorSecundario;
      }else{
        for(;i<7;i++){
          if(ValorSecundario==Modos[i][0]){
            Serial.print("Se cambia de "+String(Modo));
            Modo = i+2;
            Serial.println(" a:"+String(Modo));
            break; 
          }
        }
      }
      
    }break;
    case 2:{//confirmacion de modo
      byte ValorSecundario = data[1];//Valor real
      
        if(ValorSecundario==10){
          AccionSolicitada=(2);
          Modo_Solicitado=10;
      
        }else{
          AccionSolicitada=(2);
          Modo_Solicitado=ValorSecundario;
          //El valor secundario es la posicion del array de modos al que apunta
          //Modos[ValorSecundario][key,sensor,valor default]
        }
    }break;
    case 3:{
      byte ValorSecundario = data[1];//Valor real
      byte ValorTerciario  =data[2];//Key
      byte ValorCuaternario = data[3];
      byte ValorUltimo =  data[4];
      Modos[ValorSecundario][0]=ValorTerciario;
      // Aca seria la key del modo
      Modos[ValorSecundario][1]=ValorCuaternario;
      //El sensor que usa (0,1,2,3)
      Modos[ValorSecundario][2]=ValorUltimo;
      //Seria un valor de distancia por default en caso que el sensor este desconectado
//	  Serial.println("Se a√ɬĪade 1: "
  //                 +String(ValorSecundario)+" "
    //               +String(Modos[ValorSecundario][0])+" "
      //             +String(Modos[ValorSecundario][1])+" "
        //           +String(Modos[ValorSecundario][2]));
    }break;

  }
  
}
void EsteMetodoNoHaceNada(int t){
	//No hago nada :)
  
  //Nop, efectivamente no hace nada
  //pero algo hacia no me acuerdo que era, por eso no lo borro
}

void Peticion(){
//  if(Ocupado){Wire.write(Key_Arduino_Ocupado);return;}
  //Serial.println("Accion Solicitada : "+String(AccionSolicitada)+" y : "+String(Modo_Solicitado));
  if(Error_Ocurred){
    Wire.write(0); 
    Serial.println("Se esta enviando un error");
    Error_Ocurred=0;
  }else{
    switch(AccionSolicitada){
      case 1:{
        byte rex = AnalizarSensor(Modo-2);
        Serial.print("M "+String(rex)+" ");
        for(int i = 0; i<7;i++){
        
          Serial.print(","+String(Modos[i][3]));
        }

        Serial.println();
        byte res = 0;
        for(int i = 0; i<7;i++){
          if(i == (Modo-2)){
            res = res | rex<<i;
          }else{
            res = res | Modos[i][3]<<i;
          }
        
        }
        Serial.println("Se envia "+ String(res));
        Wire.write(res);
        //Serial.println(String(Modo)+"distancia es "+String(Modos[Modo-2][2]));
      }break;
      case 2:{
        if(Modo_Solicitado>10){Wire.write(0);break;}
        if(Modo_Solicitado==10){
          if(Modo<2){
            Wire.write((Modo));
          }else{
            Wire.write((Modos[Modo-2][0]));
          //	Serial.println("Devolvioendo "+String((Modos[Modo-2][0])));
          }
          break;
        }
        else{
 //         Serial.println("Se pide "+String(Modo_Solicitado)
   //                      +" : "+String(Modos[Modo_Solicitado][0])
     //                    +" "+String(Modos[Modo_Solicitado][1])
       //                  +" "+String(Modos[Modo_Solicitado][2]));
          Wire.write(Modos[Modo_Solicitado][0]);
          Wire.write(Modos[Modo_Solicitado][1]);
          Wire.write(Modos[Modo_Solicitado][2]);
          //Se los hay que enviar por separado
          //no se puede mandar un uint32_t porque no se que hace
          //asi q quedo mas comodo asi
        }
        
        
      }break;
    }
  }
  AccionSolicitada=0;
  Modo_Solicitado=0; 
}
long Analizar(int triggerPin, int echoPin){
  pinMode(triggerPin, OUTPUT);  // Clear the trigger
  digitalWrite(triggerPin, LOW);
  //Sets the trigger pin to HIGH state for 10 microseconds
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  pinMode(echoPin, INPUT);
  // Reads the echo pin, and returns the sound wave travel time in microseconds
  return pulseIn(echoPin, HIGH);
}

Error en valores de algunas variables en el momento de aplicar la comunicación i2c, estaría muy agradecido si alguien me pudiera dar una manito con este error.

Muchas gracias por pasarte por el post.
Ultima vez actualizado (2/11/21).

Lograste alguna vez leer algo en el Arduino Esclavo? Digo porque empezar con tanto código es como complicado a la hora de encontrar un problema
Yo simplificaría los dos códigos a su minima expresión, envio y veo que recibo, sin motores, sin cosas que molesten y compliquen.
Basicamente la comunicación, la probaste antes?

Hola Buenas si Logre mas de una vez leer datos, ahora ando leyendo un poco mas el código y sacando cosas innecesarias como me decías para ver si encuentro la vuelta

La sobrecarga de Send_To_Slave() no podrías reemplazarla por algo como

void Send_To_Slave(uint8_t numData, uint8_t data, uint8_t data1 = 0, uint8_t data2 = 0, uint8_t data3 = 0, uint8_t data4 = 0){
  Wire.beginTransmission(I2C_SLAVE_ADDR);
  if(numData >= 1) Wire.write(data);
  if(numData >= 2) Wire.write(data1);
  if(numData >= 3) Wire.write(data2);
  if(numData >= 4) Wire.write(data3);
  if(numData == 5) Wire.write(data4);
  Wire.endTransmission();
}

?

Saludos

1 Like

Maestro

#include "Wire.h"
#include <SoftwareSerial.h>       
SoftwareSerial BTSerial(12,13);

uint8_t I2C_SLAVE_ADDR =0x01;



int Codigos_de_Movimiento[7][12]={
    {0,0,0,0,0,0,0,0,500000,7,1,1},
      //[0-7]pos motores [8]tiempo [9]sensor [10]distancia minima [11]algo adelante
      {1,0,1,0,0,1,0,1,5000,0,31,1},
      {0,1,0,1,1,0,1,0,5000,1,31,1},
      {0,1,0,1,0,1,0,1,5000,7,23,1},
      {1,0,1,0,1,0,1,0,5000,7,23,1},
      {1,0,1,0,0,1,0,1,5000,2,20,1},
      {0,1,0,1,1,0,1,0,5000,3,20,1}
};


uint8_t Motor_Num[8]={2,6,10,11,A0,A1,A2,A3};

byte MovimientoActual=0;

void setup(){
  for(int i = 0;i<8;i++){pinMode(Motor_Num[i],OUTPUT);}
  Wire.begin();
  Serial.begin(9600);
  BTSerial.begin(9600);
}

void loop(){
  if(Serial.available()){
  //if(BTSerial.available()){
    
    MovimientoActual=Serial.read()-'0';
    //MovimientoActual=BTSerial.read();
    
    long TiempoInicioMovimiento = millis();
    int TiempoTranscurrido=0;
    Serial.println("Iniciando : "+String(MovimientoActual)+"por "+String(Codigos_de_Movimiento[MovimientoActual][8])+"segs");
    while(TiempoTranscurrido<Codigos_de_Movimiento[MovimientoActual][8]){
      if(Serial.available()){
    //if(BTSerial.available()){
        
        MovimientoActual=Serial.read();
        //MovimientoActual=BTSerial.read();
        
        TiempoInicioMovimiento = millis();
        TiempoTranscurrido=0;
        
        Serial.println(BTOut());
        //BTSerial.write(BTOut());

      }
      byte msj = Codigos_de_Movimiento[MovimientoActual][9]|Codigos_de_Movimiento[MovimientoActual][10]<<3;
      Send_To_Slave(msj);
      Codigos_de_Movimiento[MovimientoActual][11]= Obtener_Respuesta();
      if(Codigos_de_Movimiento[MovimientoActual][11]!=1){Serial.println("algo delante");break;}
      int t =0;
      for(int _Motor=1;_Motor<5;_Motor++){
          Motor(_Motor,Codigos_de_Movimiento[MovimientoActual][t],Codigos_de_Movimiento[MovimientoActual][t+1]);
        t+=2;
      }
      TiempoTranscurrido = millis()-TiempoInicioMovimiento;
    }
    MovimientoActual=0;
    int t =0;
    for(int _Motor=1;_Motor<5;_Motor++){
      Motor(_Motor,Codigos_de_Movimiento[MovimientoActual][t],Codigos_de_Movimiento[MovimientoActual][t+1]);
      t+=2;
    }
    Serial.println(BTOut());
    //BTSerial.write(BTOut());
  }
}

byte BTOut(){
  byte res=0;
  for(int i = 1;i<7;i++){
  res = res | Codigos_de_Movimiento[i][11]<<i;
  }
  return res;
}

bool Motor(uint8_t motor,uint8_t a,uint8_t b){
  byte c=a|b<<1;
  switch(c){
      case 3:return false;
  }
  switch(motor){
    default:return false;
      case 1:digitalWrite(Motor_Num[0],a);digitalWrite(Motor_Num[1],b);break;
    case 2:digitalWrite(Motor_Num[2],a);digitalWrite(Motor_Num[3],b);break;
    case 3:digitalWrite(Motor_Num[4],a);digitalWrite(Motor_Num[5],b);break;
    case 4:digitalWrite(Motor_Num[6],a);digitalWrite(Motor_Num[7],b);break;
  }
  return true;
}


uint8_t Obtener_Respuesta(){
  uint8_t response;
      
      Wire.requestFrom(I2C_SLAVE_ADDR, sizeof(response));
      long t = millis();
      while(Wire.available() < 1){
        long delta = millis()-t;
        if(delta>500){
          return 0;
        }
      }
      response =Wire.read();
      Serial.println("res "+String(response)); 
        return response;
}
void Send_To_Slave(uint8_t data){
  Wire.beginTransmission(I2C_SLAVE_ADDR);
  Wire.write((byte*)&data, sizeof(data));
  Wire.endTransmission();
}

Slave

#include "Wire.h" 

bool Sensores_Conectados[4]={1,1,1,1};

int Sensor_Pines[4][3]={
  {4,5,6},//adelante
  {11,12,13},//atras
  {14,15,7},//izquierda
  {16,17,8}//derecha
  
};

void setup() {
 	//CODIGO esclavo
  	Serial.begin(9600);
  for(int i = 0;i<(4);i++){
  //Trigger, OUTPUT)
  //   Echo, INPUT);
    pinMode(Sensor_Pines[i][0],OUTPUT);
    pinMode(Sensor_Pines[i][1],INPUT);
    pinMode(Sensor_Pines[i][2],OUTPUT);
    digitalWrite(Sensor_Pines[i][2],1);
  }//TestearSensores();
  Wire.begin(0x01); //identifico como esclavo 1
  Wire.onReceive(receiveEvent); //Declaro Evento
  Wire.onRequest(Peticion); //Declaro Evento
  Serial.println("Listo");
    
}
byte ProximaSolicitudSensor=0;
byte ProximaSolicitudDistanciaMinima=0;

void loop() {
  TestearSensores();
}
byte AnalizarSensor(int s,int distancia_Min){
  if(s!=7){
    if(Sensores_Conectados[s]){
      
      byte sensor =0.01723 *Analizar(Sensor_Pines[s][0],Sensor_Pines[s][1]);
      Serial.println("ND"+String(sensor));
      if((sensor>distancia_Min)){
        return 1;
      }else{ 
        return 0;
      }
     
    }else{
      return 0;
    }
  }else{
    return 1;
  }
}
bool TestearSensores(){
  for(int i = 0; i<4;i++){
    
   
      //Si el sensor no devuelve nada lo vuelve a intentar
      
      if(Analizar(Sensor_Pines[i][0],Sensor_Pines[i][1])<=0){
        //Si el sensor no devuelve nada lo vuelve a intentar
        if(Analizar(Sensor_Pines[i][0],Sensor_Pines[i][1])<=0){
          //Si el sensor no devuelve nada lo vuelve a intentar
         if(Analizar(Sensor_Pines[i][0],Sensor_Pines[i][1])<=0){
            //Cuando ocurren 3 fallos interpreta que el sensor esta desconectado
            //Si el arduino se esta ejecutando solamente muestra una advertencia en consola
            //Si se esta iniciando no le permite iniciarse
              Sensores_Conectados[i] = 0;
              digitalWrite(Sensor_Pines[i][2],0);   
            }else{
              Sensores_Conectados[i] = 1;
              digitalWrite(Sensor_Pines[i][2],1);
          }
          }else{
            Sensores_Conectados[i] = 1;
            digitalWrite(Sensor_Pines[i][2],1);
        }
        }else{
         Sensores_Conectados[i] = 1;
   	     digitalWrite(Sensor_Pines[i][2],1);
        
      }
    
    }
  
  return true;
}

void receiveEvent(int bytes){
  byte data[bytes];
  for(int i =0;i<bytes;i++){
  	data[i]=Wire.read();
  }
  ProximaSolicitudSensor=data[0]&0b00000111;
  ProximaSolicitudDistanciaMinima=data[0]>>3;
  Serial.println("Rec "+String(ProximaSolicitudSensor)+" y "+String(ProximaSolicitudDistanciaMinima));
}

void Peticion(){
  
  byte msgRespuesta=AnalizarSensor(ProximaSolicitudSensor,ProximaSolicitudDistanciaMinima);
  Serial.println("Enviando "+String(msgRespuesta));
  Wire.write(msgRespuesta);
  ProximaSolicitudSensor=0;
  ProximaSolicitudDistanciaMinima=0;
}
long Analizar(int triggerPin, int echoPin){
  pinMode(triggerPin, OUTPUT);  // Clear the trigger
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(2);
  //Sets the trigger pin to HIGH state for 10 microseconds
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  pinMode(echoPin, INPUT);
  // Reads the echo pin, and returns the sound wave travel time in microseconds
  return pulseIn(echoPin, HIGH);
}

Con este c√≥digo que estuve probando con un compa√Īero (Tiziano) que estuvo indagando un poco mas logramos hacer andar todo con el mismo diagrama, si alguien tiene algun consejo o tip se agradece, un saludo y muchas gracias por la info que aportaron.