desktop

Detector de Obstáculos con sensor ultrasónico y PIC18F2550

Buenas tardes a todos. Acudo a ustedes por una pequeña ayuda.

Estoy construyendo un detector de obstáculos para invidentes.

Este mismo consta de lo siguiente:
2 bandas en las piernas(derecha e izquierda), 2 bandas en los brazos (derecha e izquierda) y una banda en el abdomen.
Las bandas de las piernas tienen 2 ultrasónicos cada una, uno lee de frente y otro inclinado.

En el caso del abdomen, tiene 3 ultrasónicos, estos leen izquierda, centro y derecha respectivamente.

Por último, las bandas de los brazos reciben una señal que les indica cómo deben prender unos motorcitos, para que vibren diferente según sea el caso.

Los casos son los siguientes:

Distancia < 50 : Vibra 250mS se apaga 83mS (Vibra 3 veces por segundo)
Distancia > 50 y < 100 : vibra 250mS y se apaga 250mS (Vibra 2 veces por segundo)
Distancia > 100 y < 200 : vibra 250mS y se apaga 750mS (Vibra 1 vez por segundo)

Distancia > 200 : Deja de vibrar.

Todo esto lo manejo de la siguiente forma:

- Tengo 5 PIC18F2550. Uno en cada banda y abdomen.

- Las piernas, hablando del caso de que no lea ningún hueco, lee la izquierda por ejemplo una distancia de frente, digamos 10mS, esto lo pasamos a uS y nos da 10.000uS, esto para dividirlo entre 58 y nos da: 172.4cm. Este valor lo divido entre 10 y me da 17.24mS.

- El valor del ECHO = 10mS lo guardo en un registro CHAR
- El valor de microsegundos = 10.000 lo guardo en un LONG
- El valor de centímetros = 172.4cm también lo guardo en un LONG, por si leo una distancia que cause que sea mayor a 255cm

- El valor de transferencia (centímetros/10) lo estoy guardando en un CHAR, esto porque estoy limitando a las piernas a que si leen un valor mayor a 250 lo desprecien y vuelvan a leer.

Teniendo todo esto claro, el valor de transferencia (centímetros/10) lo utilizo para enviar un PING directamente proporcional a su valor desde la pierna, hacia el abdomen.
El abdomen entonces recibe un PING de 17mS, este lo toma y lo multiplica por 10, y concluye que valor recibido = 170cm.

Si consideramos que los 3 sensores ultrasónicos que tiene el abdomen están leyendo valores mayores al recibido, entonces el valor recibido (170cm) es el más importante y por ende lo debemos transmitir hacia los brazos.

Cada rango que expliqué más arriba tiene un número asignado, 1 - 2 - 3 - 4.

En el caso de recibido = 170 cm, entonces asignamos a enviar el valor de 3.
Ahora enviamos un PING de 3mS a los brazos y estos deberán entonces vibrar en los términos explicados más arriba, según esta lógica.

Dicho todo esto y entendiendo un poco este funcionamiento/lógica, estoy presentando problemas en el caso de los brazos.
Estoy simulando todo en proteus, el ultrasónico de las piernas me está leyendo el valor correctamente y el controlador también está enviando el valor correctamente.
Por ende, asumo que el controlador del abdomen está recibiendo el valor correcto.

El problema está cuando envío del controlador del abdomen a los brazos, no me está trabajando correctamente.
Espero que alguien me pueda ayudar a encontrar mi error o el problema en mis códigos.
Estaría eternamente agradecido.

Esto es mi tesis de postgrado de control avanzado de procesos. Por sencillo que parezca si :( jajajaja.

- Aclaratoria 1: Todo es simulado, el medio de comunicación planteado es inalámbrico, debido a que es simulado todo, use cables y plantee que el medio inalámbrico es ideal y sin perdida o ruido alguno.

- Aclaratoria 2: Para que las piernas transmitan deben enviar un PING de 1mS (derecha) y 2mS(izquierda), también deben recibir un PING de igual magnitud para enviar el valor de distancia leído.

Aclaratoria 3: Cuando el abdomen lee el valor proveniente de las piernas, cualquiera de las 2, envía un PING DE 6mS que sera leído por ambos brazos, indicándoles a ambos que deben activarse.

Aclaratoria 4: Si los brazos reciben el PING de 6mS y no reciben valor luego de este, entonces asumen que hay un hueco.
Si es el caso de que reciben un valor (1 - 2 - 3 - 4) luego del PING de 6mS, entonces deberá actuar según el valor que recibió.

Finalmente como les pido, asuman que una pierna está leyendo un valor y todo lo demás es despreciable.

Adjunto código de pierna izquierda, abdomen y brazo izquierdo.
Pierna derecha y brazo derecho son iguales, solo cambian los ping que envían y reciben para transmitir y recibir.

Códigos:

Pierna:
PHP:
///////////////////////////////////////////////////////////////////////////////
//  DESCRIPTION:  Procesos                                                   //
///////////////////////////////////////////////////////////////////////////////

Void Proceso_Recibir()
{
   if(Bandera_recibir == false)                                 // SI NO SE ESTA RECIBIENDO NINGUNA INFORMACION
   {                                                            // SE PERMITE EL ENVIO DE LA MISMA
      BANDERA_COMUNICACION = TRUE;
   }
   IF(bandera_sincronizacion2 == false)
   {
      if( bandera_recibir == True )                                // ESTE ES BASICAMENTE EL PROCESO QUE SIEMPRE SE ESTARA REALIZANDO
      {
         milis2 = 0 ;
         Do
         {
         }While(input(Recibir));                                   // CUANDO RECIBIMOS UN PING HIGH EN EL PIN RECIBIR(RB0) AQUI,
         Bandera_Recibir = False;                                  // CONTAMOS CUANTO TIEMPO DURA ENCENDIDO PARA SABER QUE DEBEMOS HACER       
      }
   }
   if(Bandera_inicio == true)
   {
      if(milis2 != 0 )                                         // SI EXISTE UN PING DIFERENTE A 1mS
      {
         BANDERA_COMUNICACION = FALSE ;
         milis2 = 0 ;
      }
   }
   if(Bandera_Alarma == True)                                // EN EL CASO DE QUE LA ALARMA AUN ESTE HABILITADA                                   
   {                                                         // ASUMIMOS QUE EL PROCESO AUN NO HA INICIADO
      if(milis2 == 8)                                        // SI RECIBIMOS UN PING DE 8mS ENTONCES PROCEDEMOS
      {                                                      // A INICIAR LA FASE 1 DE SINCRONIZACION Y
         Bandera_Sincronizacion1 = true ;                    // RESPONDEREMOS CON UN PING DE 1mS PARA INDICAR QUE
         milis2 = 0 ;                                        // EL SISTEMA DE LA PIERNA DERECHA ESTA LISTO PARA EMPEZAR
      }
      if(milis2 == 9)
      {
         Bandera_Sincronizacion2 = true ;                    // EN EL CASO DE RECIBIR UN PING DE 9mS PROCEDEMOS A EN DEFINITVA      
         milis2 = 0 ;                                        // INICIAR EL PROCESO Y APAGAR LA ALARMA
      }
   } 
}

//////////////////////////////////////////////////////////////////////////////

Void Proceso_Ultrasonico1()
{
   IF(BANDERA_INICIO == TRUE )
   {
      if(Bandera_Us1==True)
      {
         
         Output_High(Activar_Us1);
         Delay_us(15);
         Output_Low(Activar_Us1);
         milis = 0 ;
         Do
         {
         }While(Input(Receptor_EC1));
         
         echo = milis;
         milis = 0 ;
         Bandera_us1=False;
         micros = echo * 1000 ;
         cm = micros / 58 ;
         
         if(Bandera_Obstaculo == true)
         {
            if(cm<3)
            {
               Bandera_ObstaculoS = True ;
               Bandera_ObstaculoP = False ;
               Bandera_Obstaculo = False ;
               Bandera_Transmitir1 = True;
            }
            if(cm>50)
            {
               Bandera_ObstaculoS = True ;
               Bandera_ObstaculoP = False ;
               Bandera_Obstaculo = False;
               Bandera_Transmitir1 = True ;
            }
            if(cm>3 && cm<50)
            {
               Bandera_ObstaculoP = False ;
               BANDERA_Transmitir1 = False ;
               Bandera_us1 = True ;
               Bandera_Obstaculo1P = True ;
               Bandera_Obstaculo = True ;
               bandera_transmitir2 = false;
            }
         } 
         
         if(Bandera_Obstaculo1P == False)
         {
            if(cm>3 && cm<50)
            {
               Bandera_ObstaculoP = True ;
               Bandera_Transmitir1 = True ;
               Bandera_us2 = False ;
               Bandera_us1 = True ;
               bandera_transmitir2 = false;
            }
            else
            {
               Bandera_ObstaculoP = False ;
               Bandera_Obstaculo = False ;
               Bandera_ObstaculoS = False ;
               Bandera_Transmitir1 = False ;
               Bandera_Obstaculo1P = False ;
               Bandera_us1 = false ;
               Bandera_us2 = true ;
            }
         }
      }
   }
}

//////////////////////////////////////////////////////////////////////////////

Void Proceso_Ultrasonico2()
{
   IF(BANDERA_INICIO == TRUE )
   {
      if(bandera_obstaculo == false)
      {
         if(Bandera_Us2==True)
         {
            Output_High(Activar_Us2);
            Delay_us(15);
            Output_Low(Activar_Us2);
            milis = 0 ;
            Do
            {
            }While(Input(Receptor_EC2));
            echo = milis;
            milis = 0 ;
            Bandera_us2=False;
            micros = echo * 1000 ;
            cm = micros / 58 ;
            trans = cm / 10 ;
            if(cm > 250)
            {
               BANDERA_US1 = TRUE ;
               BANDERA_TRANSMITIR2 = FALSE;
            }
            IF(CM < 250)
            {
               IF(CM == TRANS)
               {
                  BANDERA_US1 = TRUE;
                  BANDERA_TRANSMITIR2 = false ;
               }
               IF(CM != TRANS)
               {
               BANDERA_TRANSMITIR2 = TRUE ;
               }
            
            }
            if(bandera_comunicacion == false)
            {
               bandera_us1 = true ;
            }
         }
      }
   }
}

//////////////////////////////////////////////////////////////////////////////

Void Proceso_Transmitir()
{
   IF(BANDERA_INICIO == TRUE )
   {
      if(Bandera_Comunicacion == TRUE)
      {
         if(Bandera_Transmitir1 == True )
         {
            if(Bandera_ObstaculoP == True )
            {
               Disable_Interrupts(int_ext);
               milis = 0 ;
               Output_High(Enviar);
               Do
               {
               }While(milis<5);
               Output_low(Enviar);
               Enable_interrupts(int_ext);
               Bandera_Transmitir1 = False ;
               Bandera_ObstaculoP = False ;
               Bandera_Us1 = True ;
               Bandera_Obstaculo = True;
               Bandera_Obstaculo1P = True;
            }
            if(Bandera_ObstaculoS == True )
            {
               Disable_Interrupts(int_ext);
               milis = 0 ;
               Output_High(Enviar);
               Do
               {
               }While(milis<5);
               Output_low(Enviar);
               Enable_interrupts(int_ext);
               Bandera_Transmitir1 = False ;
               Bandera_ObstaculoP = False ;
               Bandera_Us2 = True ;
               Bandera_Us1 = False ;
               Bandera_Obstaculo = False;
               Bandera_Obstaculo1P = False;
               Bandera_ObstaculoS = False ;               
            }
         }
         if(Bandera_Transmitir2 == True )
         {
         
            disable_interrupts(int_ext);
            output_high(enviar);
            milis=0;
            Do
            {
            }while(milis<2);
            output_low(enviar);
            milis = 0 ;
            do
            {
            }while(milis<1);
            milis=0;
            output_high(enviar);
            do
            {
            }while(milis<trans);
            output_low(enviar);
            milis=0;
            enable_interrupts(int_ext);
            bandera_transmitir2 = false ;
            BANDERA_US1 = TRUE ;
            
         }
      }
   }
}
Abdomen:
PHP:
///////////////////////////////////////////////////////////////////////////////
//  DESCRIPTION:  Procesos                                                   //
///////////////////////////////////////////////////////////////////////////////

Void Proceso_Ultrasonicos()
{
   IF(Bandera_ultrasonicos == true)
   {
      if(Bandera_Us1==True)
      {
         Output_High(Activar_Us1);
         do
         {
         }while(milis<1);
         Output_Low(Activar_Us1);
         milis = 0 ;
         Do
         {
         }While(Input(Receptor_EC1));
         echo = milis;
         milis = 0 ;
         Bandera_us1=False;
         micros = echo * 1000 ;
         cm = micros / 58 ;
         distancia1 = cm ;
         micros = 0 ;
         milis = 0 ;
         echo = 0 ;
         Bandera_us2=true;
      }
      if(Bandera_Us2==True)
      {
         Output_High(Activar_Us2);
         do
         {
         }while(milis<1);
         Output_Low(Activar_Us2);
         milis = 0 ;
         Do
         {
         }While(Input(Receptor_EC2));
         echo = milis;
         milis = 0 ;
         Bandera_us2=False;
         micros = echo * 1000 ;
         cm = micros / 58 ;
         distancia2 = cm ;
         micros = 0 ;
         milis = 0 ;
         echo = 0 ;
         Bandera_us3=true;
      }
      if(Bandera_Us3==True)
      {
         Output_High(Activar_Us3);
         milis = 0;
         do
         {
         }while(milis<1);
         Output_Low(Activar_Us3);
         milis = 0 ;
         Do
         {
         }While(Input(Receptor_EC3));
         echo = milis;
         milis = 0 ;
         Bandera_us3=False;
         micros = echo * 1000 ;
         cm = micros / 58 ;
         distancia3 = cm ;
         micros = 0 ;
         milis = 0 ;
         echo = 0 ;
         bandera_calculo = true ;
         bandera_ultrasonicos = false ;
         bandera_us1 = true ;
      }
      
   }
}

//////////////////////////////////////////////////////////////////////////////

Void Proceso_Recibir()
{
   if(bandera_Comunicacion == true )
   {
      milis2 = 0;
      do
      {
      }while(input(recibir));
      bandera_recibir = false ;
      rec = milis2 ;
      milis2 = 0;
      bandera_responder = true ; 
     
   }
}


///////////////////////////////////////////////////////////////////////////////

Void Proceso_Actuar()
{

   if(bandera_responder == true )
   {
   
      switch (rec)
      {
         case 1:
         
         Disable_interrupts(int_ext);
         output_high(enviar);
         milis = 0 ;
         Do
         {
         }While(milis<1);
         output_low(enviar);
         enable_interrupts(int_ext);
         Do
         {
            milis2=0;
         }While(bandera_Recibir==false);
         do
         {
         }while(input(recibir));
         bandera_recibir = false ;
         bandera_calculo = true ;
         bandera_responder = false ;
         r = milis2 ;
            
         break;
         
         case 2:
         
         Disable_interrupts(int_ext);
         output_high(enviar);
         milis = 0 ;
         Do
         {
         }While(milis<2);
         output_low(enviar);
         enable_interrupts(int_ext);
         Do
         {
            milis2=0;
         }While(bandera_Recibir==false);
         do
         {
         }while(input(recibir));
         bandera_recibir = false ;
         bandera_calculo = true ;
         bandera_responder = false ;
         r = milis2 ;
         
         break;
           
         case 5:
         
         if(prioridad == 0)
         {
            bandera_prioridad = true ;
            bandera_ultrasonicos = false ;
            prioridad++;
         }
         if(prioridad == 1)
         {
            bandera_prioridadd = true ;
            bandera_ultrasonicos = true ;
            prioridad = 0 ;
         }
         
         break ;
         
         default:
         
         break;
   
      }
   }
   if(bandera_prioridad == true)
   {
      Disable_interrupts(int_ext);
      output_high(enviar);
      milis = 0 ;
      Do
      {
      }While(milis<6);
      output_low(enviar);
      enable_interrupts(int_ext);
      bandera_prioridad = false ;
   }
   if(bandera_prioridadd == true)
   {
      Disable_interrupts(int_ext);
      output_high(enviar);
      milis = 0 ;
      Do
      {
      }While(milis<6);
      output_low(enviar);
      enable_interrupts(int_ext);
      bandera_prioridad = false ;
   }
   
   if(prioridad == 0)
   {
      if(bandera_Calculo == true)
      {
    
         distancia4 = r * 10 ;
         If(distancia1<distancia2)               
         {                                      
            if(Distancia1<distancia3)
            {
               if(Distancia1<Distancia4)
               {
                  comp = distancia1 ;
               }
            }
         }
         if(Distancia2<Distancia3)
         {
            if(Distancia2<Distancia4)
            {
               comp = distancia2;
            }
         }
         if(distancia3<distancia4)
         {
            comp = distancia3 ;
         }else
         {
            comp = distancia4 ;
         }
         
         if(COMP != COMP2)
         {
            if(comp < 250)
            {
               if(comp<50)
               {
      
                  act = 1 ;                     //asignamos un valor a la variable ACT para transmitirlo
                                                //cada valor asignado a un limite y cada uno de estos,
               }                                //vibra a una frecuencia diferente para diferenciarlos
               if( comp>50 && 100>comp)
               {
                  act = 2 ;     
               }
               if(comp>100 && 200<comp)
               {
                  act = 3 ;
               }
               if(comp>200)
               {
               act = 4 ;
               }
         
               BANDERA_TRANSMITIR = TRUE ;
               bandera_calculo = false ;
            }
            if(comp>250)
            {
               
               BANDERA_TRANSMITIR = TRUE ;
               bandera_calculo = false ;
               ACT = 4 ;
            }
     
         }
         IF(COMP == COMP2)
         {
            BANDERA_TRANSMITIR = FALSE ;
            BANDERA_ULTRASONICOS = TRUE ;
         }
      }
   }
   if(bandera_transmitir == true )
   {
      COMP2 = COMP;
   
      if(comp == distancia1)
      {
         
         Disable_interrupts(int_ext);
         output_high(enviar);
         milis = 0 ;
         Do
         {
         }While(milis<3);
         output_low(enviar);
         enable_interrupts(int_ext);
         milis = 0 ;
         Do
         {
         }While(milis<1);
         Disable_interrupts(int_ext);
         output_high(enviar);
         milis = 0 ;
         Do
         {
         }While(milis<act);
         output_low(enviar);
         enable_interrupts(int_ext);
         
           
      }
      if(comp == distancia2)
      {
         Disable_interrupts(int_ext);
         output_high(enviar);
         milis = 0 ;
         Do
         {
         }While(milis<6);
         output_low(enviar);
         enable_interrupts(int_ext);
         milis = 0 ;
         Do
         {
         }While(milis<1);
         Disable_interrupts(int_ext);
         output_high(enviar);
         milis = 0 ;
         Do
         {
         }While(milis<act);
         output_low(enviar);
         enable_interrupts(int_ext);
         
      }
      if(comp == distancia3)
      {
         Disable_interrupts(int_ext);
         output_high(enviar);
         milis = 0 ;
         Do
         {
         }While(milis<4);
         output_low(enviar);
         enable_interrupts(int_ext);
         milis = 0 ;
         Do
         {
         }While(milis<1);
         Disable_interrupts(int_ext);
         output_high(enviar);
         milis = 0 ;
         Do
         {
         }While(milis<act);
         output_low(enviar);
         enable_interrupts(int_ext);
         
      }
      if(comp == distancia4)
      {
         Disable_interrupts(int_ext);
         output_high(enviar);
         milis = 0 ;
         Do
         {
         }While(milis<6);
         output_low(enviar);
         enable_interrupts(int_ext);
         milis = 0 ;
         Do
         {
         }While(milis<1);
         Disable_interrupts(int_ext);
         output_high(enviar);
         milis = 0 ;
         Do
         {
         }While(milis<act);
         output_low(enviar);
         enable_interrupts(int_ext);
         
      }
      BANDERA_TRANSMITIR = FALSE ;
   }
   Bandera_ultrasonicos = true ;
}
Brazo:
PHP:
///////////////////////////////////////////////////////////////////////////////
//  DESCRIPTION:  Procesos                                                   //
///////////////////////////////////////////////////////////////////////////////

Void Proceso_Recibir()
{
   if( bandera_recibir == True )                                // ESTE ES BASICAMENTE EL PROCESO QUE SIEMPRE SE ESTARA REALIZANDO
   {
      milis2 = 0 ;
      Do
      {
      }While(input(Recibir));                                   // CUANDO RECIBIMOS UN PING HIGH EN EL PIN RECIBIR(RB0) AQUI,
      Bandera_Recibir = False;                                  // CONTAMOS CUANTO TIEMPO DURA ENCENDIDO PARA SABER QUE DEBEMOS HACER
      proc = milis2 ;
      bandera_actuar = true ;
   }
   if(Bandera_Alarma == True)                                // EN EL CASO DE QUE LA ALARMA AUN ESTE HABILITADA                                   
   {                                                         // ASUMIMOS QUE EL PROCESO AUN NO HA INICIADO
      if(milis2 == 8)                                        // SI RECIBIMOS UN PING DE 8mS ENTONCES PROCEDEMOS
      {                                                      // A INICIAR LA FASE 1 DE SINCRONIZACION Y
         Bandera_Sincronizacion1 = true ;                    // RESPONDEREMOS CON UN PING DE 1mS PARA INDICAR QUE
         milis2 = 0 ;                                        // EL SISTEMA DE LA PIERNA DERECHA ESTA LISTO PARA EMPEZAR
      }
      if(milis2 == 9)
      {
         Bandera_Sincronizacion2 = true ;                    // EN EL CASO DE RECIBIR UN PING DE 9mS PROCEDEMOS A EN DEFINITVA      
         milis2 = 0 ;                                        // INICIAR EL PROCESO Y APAGAR LA ALARMA
      }
   } 
}


//////////////////////////////////////////////////////////////////////////////

Void Proceso_Actuar()
{
   if(bandera_actuar == true)
   {
      switch (proc)
      {
         case 4:
         
         do
         {
         milis2 = 0;
         }while(bandera_recibir == false);
         do
         {
         }while(input(recibir));
         bandera_recibir = false ;
         act = milis2;
         bandera_actuar2 = true ;
         BANDERA_ACTUAR = FALSE ;
         
         break ;
         
         case 6:
         
         milis = 0 ;
         do
         {
            milis2 = 0;
         }while(milis<1);
         
         if(bandera_recibir == false)
         {
            if(com == 0)
            {
               bandera_prioridad = true ;
               com++;
            }
            
            if(com == 1)
            {
               bandera_prioridad2 = true ;
               com = 0 ;
            }
         }
         if(bandera_recibir == true )
         {
            do
            {
            }while(input(recibir));
            bandera_recibir = false ;
            act = milis2;
            bandera_actuar3 = true ;
         }
         BANDERA_ACTUAR = FALSE ;
         
         break ;
         
         default:
         bandera_actuar = false ;
         output_low(actuador);
         break ;
      }
   }
   if(bandera_prioridad == true)
   {
      Output_high(Actuador);
      bandera_prioridad = false ;
   }
   if(bandera_prioridad2 == true)
   {
      output_low(actuador);
      bandera_prioridad2 = false ;
   }
   if(bandera_actuar2 == true)
   {
      switch (act)
      {
         case 1 :
         
         milis = 0 ;
         Output_High(Actuador);                              // SE ENCIENDE EL ACTUADOR POR 250mS
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_Low(Actuador);                               // SE APAGA POR 83mS
         do
         {
         }While(milis<83);                                
         milis = 0;
         Output_High(Actuador);                              // SE VUELVE A ENCENDER POR 250mS
         Do
         {
         }While(milis<250);                               
         milis = 0 ;
         Output_Low(Actuador);                               // SE APAGA NUEVAMENTE POR 83mS
         do 
         {
         }While(milis<83);
         milis = 0 ;
         Output_High(Actuador);                              // SE VUELVE A ENCENDER POR 250mS                     
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_Low(Actuador);                            // Y FINALMENTE SE APAGA POR OTROS 83mS
         do 
         {
         }While(milis<83);                                // SI NO SE HA RECIBIDO UN PING DE 10mS EN MILIS2 (RB0), SE REINICIA EL PROCESO
         milis = 0;
         
         break ;
         
         case 2 :
         
         milis = 0 ;
         Output_High(Actuador);                              // ENCENDEMOS EL ACTUADOR POR 250mS
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_Low(Actuador);                               // LO APAGAMOS POR 250mS
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_High(Actuador);                              // ENCENDEMOS NUEVAMENTE POR 250mS                          
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_Low(Actuador);                               // FINALMENTE LO APAGAMOS POR 250mS
         Do
         {
         }While(milis<250);                                  // SI NO SE HA RECIBIDO UN PING DE 10mS EN MILIS2 (RB0), SE REINICIA EL PROCESO
         milis = 0 ;
         
         break ;
         
         case 3 :
         
         milis5 = 0 ;
         milis = 0 ;
         Output_high(Actuador);                              // SE ENCIENDE EL ACTUADOR POR 250mS
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_Low(Actuador);                            // SE APAGA EL ACTUADOR POR 250mS
         milis5++;
         Do
         {
         }While(milis<250);                               
         milis = 0 ;
         milis5++ ;
         Do
         {
         }While(milis<250);                                  // PERMANECE APAGADO OTROS 250mS
         milis = 0 ; 
         milis5++ ;                           
         Do
         {
         }While(milis<250);                                  // Y FINALMENTE OTROS 250mS PARA 750mS
         milis = 0 ;                                         // SI NO SE HA RECIBIDO UN PING DE 10mS EN MILIS2 (RB0), SE REINICIA EL PROCESO
         milis5 = 0 ;
         
         break ;
         
         case 4 :
         
         output_low(actuador);
         bandera_actuar2 = false ;
         
         break ;
      }
   }
   if(bandera_actuar3 == true)
   {
      switch (act)
      {
         case 1 :
         
         milis = 0 ;
         Output_High(Actuador);                              // SE ENCIENDE EL ACTUADOR POR 250mS
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_Low(Actuador);                               // SE APAGA POR 83mS
         do
         {
         }While(milis<83);                                
         milis = 0;
         Output_High(Actuador);                              // SE VUELVE A ENCENDER POR 250mS
         Do
         {
         }While(milis<250);                               
         milis = 0 ;
         Output_Low(Actuador);                               // SE APAGA NUEVAMENTE POR 83mS
         do 
         {
         }While(milis<83);
         milis = 0 ;
         Output_High(Actuador);                              // SE VUELVE A ENCENDER POR 250mS                     
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_Low(Actuador);                            // Y FINALMENTE SE APAGA POR OTROS 83mS
         do 
         {
         }While(milis<83);                                // SI NO SE HA RECIBIDO UN PING DE 10mS EN MILIS2 (RB0), SE REINICIA EL PROCESO
         milis = 0;
         
         break ;
         
         case 2 :
         
         milis = 0 ;
         Output_High(Actuador);                              // ENCENDEMOS EL ACTUADOR POR 250mS
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_Low(Actuador);                               // LO APAGAMOS POR 250mS
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_High(Actuador);                              // ENCENDEMOS NUEVAMENTE POR 250mS                          
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_Low(Actuador);                               // FINALMENTE LO APAGAMOS POR 250mS
         Do
         {
         }While(milis<250);                                  // SI NO SE HA RECIBIDO UN PING DE 10mS EN MILIS2 (RB0), SE REINICIA EL PROCESO
         milis = 0 ;
         
         break ;
         
         case 3 :
         
         milis5 = 0 ;
         milis = 0 ;
         Output_high(Actuador);                              // SE ENCIENDE EL ACTUADOR POR 250mS
         Do
         {
         }While(milis<250);
         milis = 0 ;
         Output_Low(Actuador);                            // SE APAGA EL ACTUADOR POR 250mS
         milis5++;
         Do
         {
         }While(milis<250);                               
         milis = 0 ;
         milis5++ ;
         Do
         {
         }While(milis<250);                                  // PERMANECE APAGADO OTROS 250mS
         milis = 0 ; 
         milis5++ ;                           
         Do
         {
         }While(milis<250);                                  // Y FINALMENTE OTROS 250mS PARA 750mS
         milis = 0 ;                                         // SI NO SE HA RECIBIDO UN PING DE 10mS EN MILIS2 (RB0), SE REINICIA EL PROCESO
         milis5 = 0 ;
         
         break ;
         
         case 4 :
         
         output_low(actuador);
         bandera_actuar3 = false ;
         
         break ;
      }
   }
}
En el caso de la interrupciones:

Para medir el tiempo uso TMR1 con un oscilador de 8 Mhz interno.
Se desborda cada 1mS. Tiene asignado el valor de 63536.

y lo tengo configurado en terminos generales, de la siguiente manera:

Interrupción para el Timer 1:

PHP:
#int_TIMER1                                                      /////////////////////////////////////////////////////
void TIMER1_isr(void)                                            //Función de interrupción por desbordamiento TMR1  //
{                                                                /////////////////////////////////////////////////////
   if(bandera_alarma == true)                                    // Funcion para contar el tiempo
   {                                                             // para iniciar la alarma
      milis3++ ;                             
      if(milis3>100)
      {
         milis4++ ;
         milis3 = 0 ;
      }
   }
 
   if(Bandera_Recibir == True)                                   // Funcion para contar cuanto
   {                                                             // Tiempo esta en HIGH el pin RECIBIR
      milis2++;
   }
   
   milis++;                                                      // Conteo de 1mS en 1mS de uso General
   if(milis==252)
   {
      milis = 0 ;
   }
   set_timer1(Valor_TMR1);                                       // Reinicio del Timer1 antes de salir
}
Para recibir información utilizo la interrupcion externa de RB0, cada vez que recibo algo, activo la bandera recibir, esto me activa el contador milis2, y con este mido la duracion de los PING.
PHP:
#INT_EXT
void EXT_isr(void)
{
   BANDERA_RECIBIR = TRUE;                                       // Se enciende la bandera para indicar que el Pin Recibir esta en High
   CLEAR_INTERRUPT(INT_EXT);                                     // Se limpia la interrupcion antes de salir
   
}
Anexo también:
Todo el proyecto, incluye los códigos de todos los controladores, el hex de los ultrasónicos y la simulación en proteus.

Observación:
También he usado el osciloscopio del proteus para revisar que los ultrasónicos estén enviado a los controladores los valores correctos y que los controladores estén enviando al central también el valor correcto.
Tengo dudas con el envío del controlador al brazo o cómo el brazo interpreta lo que le llega.

Espero puedan ayudarme. Agradecido cómo siempre.
 

Adjuntos

  • proyecto-final.rar
    836.6 KB · Visitas: 16
Última edición por un moderador:
Puedes debugear el código extrayendo las medidas, viendo si el problema es la medida o la forma de disparo de los sensores, trata que el pic te de un_aviso en la mayor parte de las lineas mediante serial asi es como debugeo el código sin necesidad de una lcd.

Y de ahi aprovechas que el modulo inalámbrico sea un modulo bluetooht, además es la forma mas portatil y accesible para poder decirle al paciente en que tramo debería ir, sería que le avise por medio de vibracion o audios grabados, suerte.
 
Última edición por un moderador:
puedes debugear el codigo extraendo las medidas viendo si el problema es la medida o la forma de disparo de los sensores trata que el pic te de una viso en la mayor parte de las lineas me diante serial asi es como debugeo el codigo sin necesidad de una lcd y de ahi aprovechas que el modulo inalambrico sea un modulo bluetooht ademas es la forma mas portatil y accesible para poder decirle al paciente en que tramo deberia ir seria que le avise por medio de vibracion o audios grabados suerte

Excelente! muchas gracias, ya varias personas me han hecho la misma sugerencia.

Actualmente lo estoy probando y no me muestra nada en los terminales virtuales.

Estoy usando lo siguiente.

PHP:
#FUSES INTRC_IO                  // Internal Crystal
#FUSES NOWDT                     // No Watch Dog Timer
#FUSES NOMCLR                    // No master clear
#FUSES WDT128                    // Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT                // No brownout reset
#FUSES NOPBADEN                  // PORTB pins are configured as digital I/O on RESET
#FUSES NOLPT1OSC                 // Timer1 configured for higher power operation
#FUSES NOLVP                     // No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST                   // Extended set extension and Indexed Addressing mode disabled
#FUSES PUT                       // Espera unos mS a que se estabilice la tensión antes de iniciar.
#use delay(clock=8Mhz, internal) // CRISTAL INTERNO Y CONFIGURADO A OSCILAR A 8MHz
#use rs232(baud=9600,parity=N,xmit=PIN_B1,rcv=PIN_B2,bits=8)


y para enviar informacion a los terminales, estoy usando

PHP:
putc(act)

putc(trans)

ACT y TRANS son registros de tipo CHAR. Alguna idea de que pueda estar pasando?

Ya lo he arreglado usando la funcion siguiente

PHP:
printf("distancia medida %ldcm\n\r",cm);

estare revisando y buscando el error y comentare! gracias por la ayuda! :)
 
Última edición:
Debes darle un formato a lo que envías, o no verás nada.
No es lo mismo interpretar caracteres como texto, que en ASCII
Por ejemplo: printf("ACT = %u\r\n",act);

PD: También puedes depurar con proteus.
 
Debes darle un formato a lo que envías, o no verás nada.
No es lo mismo interpretar caracteres como texto, que en ASCII
Por ejemplo: printf("ACT = %u\r\n",act);

PD: También puedes depurar con proteus.


muchisimas gracias por tu respuesta, ya he realizado el chequeo, y el problema esta en mi controlador central.

alguna idea de que puede estar pasando?

Basicamente el central no me esta haciendo nada, no esta leyendo nada bien, ni los ultrasonicos que controla ni la información que recibe.

///

Edit:

Voy a cambiar toda la forma de comunicacion con este rs232 y les dire como me va :) espero este cambio de mi comunicacion improvisada a rs232 me de buenos resultados :)
 

Adjuntos

  • prueba.jpg
    prueba.jpg
    107.9 KB · Visitas: 22
Última edición:
Bueno! les cuento! me olvide del RS232 porque obviamente no contaba/recordaba con que es comunicacion punto punto, lei por ahi que habia forma fisica de hacerlo trabajar multipunto, pero BLE, me rendi porque me quedaba muy poco tiempo para la entrega (hoy).

Dicho esto, empece a leer y me encontre con i2c, que nunca he usado... Nunca habia hecho proyectos que tuvieran que controlar mas de 2 pic, normalmente hago todo con 1 y me basta. Vi que para hacerlo funcionar bien bien, debia hacer algo complejo y por tiempo no me fue factible.

Asi que volvi a mi primera idea pero esta vez la uni a la metodologia del I2C.

Antes, los controladores de las piernas le decian al central que le iban a transmitir. Este recibia y luego le enviaba a los brazos.

Ahora, he agregado un 6to controlador.

C1 = MAESTRO
C2 = ESCLAVO 1 - CONTROL DE ULTRASONICOS EN ABDOMEN
C3 = ESCLAVO 2 - CONTROL DE ULTRASONICOS EN PIERNA DERECHA
C4 = ESCLAVO 3 - CONTROL DE ULTRASONICOS EN PIERNA IZQUIERDA
C5 = ESCLAVO 4 - CONTROL DE RESONADOR EN BRAZO DERECHO
C6 = ESCLAVO 5 - CONTROL DE RESONADOR EN BRAZO IZQUIERDO

Entonces ahora, los 3 ultrasonicos siempre estan leyendo informacion, el maestro los activa 1 por 1 en orden, para que le transmitan info, luego de recibir de los 3, este hace sus calculos y habilita a los ultimos 2, espera respuesta de ambos y (1 responde primero y luego el otro) y teniendo estas 2 respuestas, procede a enviarles la informacion.

Tiene aun algunos detalles menores que puedo solucionar para el dia de la defensa, pero ya hoy lo puedo entregar :).

Forma de comunicacion :

RB0 = recibir

RC0 = enviar

enciendo RC0 durante tiempos ya definidos y mido estos tiempos con la interrupcion de RB0, asi estoy trabajando, y bueno, me funciono.

Si alguien tiene alguna mejor idea, sera bienvenida :D! Espero estas ideas locas mias, le funcionen a otro! :D!
 
¿Es obligatorio usar tantos uC?
creo firmemente que basta y sobra con un solo uC, bueno taaaaaaal vez dos pero no mas que eso.

Si obvio, pero la finalidad de este es plantear una especie de sistema de deteccion de obstaculos para una persona con perdida de la vista.

Este tendra 5 bandas, 1 en cada pierna y brazo y 1 en el abdomen.

Tendra sensores en las piernas para detectar huecos/baches/boca de alcantarillas/muros bajos/aceras/bebes/mascotas

En los brazos tendra los actuadores y en el abdome una lectura general de que hay a su alrededor.

Salu2
 
Entiendo que tú meta sea innovadora, peeero a su vez debe ser práctica. Veo complicado, la colocación de los brazaletes en las extremidades y el cinturón, etc, etc.; y en épocas de verano puede resultar molesto.
Más bien pensaría en algún casco con sensores ultrasonicos. Entonces según se gire la cabeza, permanentemente indicará posibilidades de obstáculos.
 
Hola buenas tardes, tengo un pequeño problema con un sensor HC-SR04, no puedo calcular los valores como debe ser, pero quisiera saber como probar que el sensor funcione correctamente?? porque me preocupa que el sensor este dañado, y otra no se si exista algun problema con mi codigo el cual anexo, basicamente este problema es parte de carrito que funciona con bluetooth el cual quiero que se frene para no chocar, mis pruebas preeliminares son encender un led en rojo cuando la distancia sea menor a 6cm y el led sea verde para mayor a 21cm, el led es RGB, gracias y espero haber sido claro, muchas gracias por la ayuda, saludos

PHP:
DEFINE OSC 48   'FRECUENCIA PARA LOS CALCULOS DE RETARDO          
          
'----------------------REGISTROS----------------------------------
ADCON1 = %00001111  'TODOS LOS PINES DIGITALES

TRISC = 0
TRISB = %00000010

'----------------------VARIABLES----------------------------------------
CR CON 13  'VALOR ASCII DEL 13 DECIMAL ES CR "RETORNO DE CARRO"
TIEMPO VAR BYTE
DISTANCIA VAR BYTE

'-----------------------ALIAS--------------------------------------------

SYMBOL ECO = PORTB.1
SYMBOL DISPARO = PORTB.0
SYMBOL RED = PORTC.0
SYMBOL GREEN = PORTC.1
SYMBOL BLUE = PORTC.2 

CLEAR 'BORRA TODAS LAS VARIABLES

PORTB = 0
PORTC = 0

HSEROUT ["INICIE",CR]
INICIO:

DISPARO = 1
PAUSEUS 10
DISPARO = 0
PULSIN ECO,1,TIEMPO
DISTANCIA = (TIEMPO/58)

IF DISTANCIA > 21 THEN
    RED = 0
    GREEN = 1
    BLUE = 0
ENDIF

IF DISTANCIA < 6 THEN
    RED = 1
    GREEN = 0
    BLUE = 0
    PORTD = 0
ENDIF

HSEROUT [DEC DISTANCIA, "CM",CR]
PAUSE 1000
GOTO INICIO
END
 
el tiempo que mide el sensor y recibe el microcontrolador esta en Milisegundos, tu division esta mal planteada.

El tiempo medido debes multiplicarlos x 1000 y luego dividirlo entre 58.

Al multiplicarlo por 1000 pasarias de Milisegundos a Microsegundos. La formula del fabricante es

Distancia en CM = Tiempo en uS (Microsegundos) / 58 .

Nunca vas a conseguir siquiera que tu calculo sea 1 debido a que lo maximo que lee el sensor son 30mS. Que se toma como que no hay obstaculo.

Realmente no me tome la molestia de buscar entender a profundidad todo, pero por lo que leo, ese es tu problema. Cambia eso y avisas que tal te fue.
 
Última edición:
Un ejemplo de usar el HC_SR04 como funcion del cual se puede modificar para
usar varios pines y no usar tantos microcontroladores.

El Ejemplo COmpleto esta

https://www.forosdeelectronica.com/f24/probando-ejemplos-xc8-99800/

Código:
float Read_Sensor_HC_SR04(void)
{

    static float count = 0;
    
    TMR1_WriteTimer(0);
    
    TRIGGER_SetHigh();
    __delay_us(10);
    TRIGGER_SetLow();
    
    while(!ECHO_GetValue());
    
    TMR1_StartTimer();
    
    while(!TMR1_HasOverflowOccured() && ECHO_GetValue());
    
    TMR1_StopTimer();
    
    if(TMR1_HasOverflowOccured()){
    
        PIR1bits.TMR1IF = 0;
        count = -1;
    
    }else{
    
        count = TMR1_ReadTimer()/2;
        count = (count/58);
    
    }
    
    return count;

}
 
Hola de antemano muchas gracias por tomarse el tiempo de contestar, les comento ya logre solucionar el detalle, de esos momento que no puedes dormir y a las 3 de la mañana se te ocurre la respuesta XD, es lo que amo de programar, bueno en fin, el problema estaba en la variable que almacena el tiempo en esta caso mi variable se llama tiempo jeje que original, pero la tenia declarada como BYTE cuando realmente debe ser WORD ya que con byte el maximo tiempo que podria medir es 255 que dividido entre 58 me daba 4, no podria medir mas de eso, ahora con WORD puedo medir el maximo del fabricante en este caso entiendo 2 metros que equivaldria a 11600uS, ya funciona a la perfeccion,

gracias nuevamente, saludos :)
 
Atrás
Arriba