Programa de "ascensor"

Hace un rato largo he visto alguien que preguntaba sobre montacargas y tal y se me ha ocurrido que podría intentarlo. Es mi primer intento con el 16f877, ya que lo básico lo tengo asumido y solo quería aumentar el volumen y complejidad...

El caso es que primero, me detectaba bien en qué piso estaba (y ahora incluiré una imagen del circuito simulado) y cambiaba "perfectamente" el display (a excepción de que me da la salida negada :eek:, de lo que ya me ocuparé), pero los botones de "llamada" no daban señales de vida y por lo tanto los indicadores de ascenso/descenso no lucían.

Una vez arreglado esto ultimo simplemente cambiando en la simulación la interrupción en RB0 como flanco descendente, ha ocurrido la inversa: llamada bien, indicadores bien, pero "sensores" y display, nada. Y ya he intentado de todo, no se me ocurre nada y sigue igual. Cabe decir que utilizo todas las interrupciones que ofrece el puerto B.

Y ahora en cuanto al diseño de la simulación: como botones de llamada (A la izquierda + botón) he utilizado una combinación de interruptores (que hay que manejar uno a uno) para que al pulsar el botón se produzca interrupción en RB0 y lea el puerto A. Como "sensores de posición" he utilizado los interruptores de la derecha en el resto de pines que también tienen interrupción del puerto B, añadiendo además otra línea para evitar rebotes y retornos... Los LEDs indican hacia arriba o hacia abajo y el display la situación actual.

Añado que he intentado también simular las interrupciones con flanco descendente y nada.

Y aquí el código:
Código:
#include <16f877.h>
#use delay(clock=4000)
#byte porta=0x05
#byte portb=0x06
#byte portc=0x07
#byte portd=0x08
#byte trisa=getenv("SFR:TRISA")
#byte trisb=getenv("SFR:TRISB")
#byte trisc=getenv("SFR:TRISC")
#byte trisd=getenv("SFR:TRISD")
#fuses NOWDT

int piso, modo, actual=0;

#int_ext
void isr_b0(){
   if (modo==0){ //si está en marcha no cambia nada
   if (porta==0b000001){
      piso=0;}
   if(porta==0b000010){
      piso=1;}
   if(porta==0b000100){
      piso=2;}
   if(porta==0b001000){
      piso=3;}}
   if (actual==piso){
      modo=0;} //parado, no tiene sentido
   if(actual<piso){
      modo=1; //subiendo
      portc=0b00000001;}
   if(actual>piso){
      modo=2; //bajando
      portc=0b00000010;}
    }

#int_rb
void isr_rb(){ 
   if(portb==0b00010000){
      actual=0; //estás en el bajo
      portd=0;
      if(actual==piso){
         modo=0; //y si estás ahí no te muevas
         portc=0;}
      while(portb==0b00010000); //espera a que suelte el interruptor
   }
   if(portb==0b00100000){
      actual=1; //estás en el piso 1
      portd=1;
      if(actual==piso){
         modo=0;
         portc=0;}
      while(portb==0b00100000);
   }
   if(portb==0b01000000){
      actual=2;
      portd=2;
      if(actual==piso){
         modo=0;
         portc=0;}
      while(portb==0b01000000);
   }
   if(portb==0b10000000){
      actual=3;
      portd=3;
      if(actual==piso){
         modo=0;
         portc=0;}
      while(portb==0b10000000);
   }
   }

void main(){
   piso=0;
   modo=0;
   actual=0;
   portb=0;
   porta=0;
   portc=0;
   portd=0;
   trisa=0xff;
   trisb=0xff;
   trisc=0;
   trisd=0;
   while(1){
      enable_interrupts(int_ext);
   enable_interrupts(int_rb);
   ext_int_edge(l_to_h);
   enable_interrupts(global);
      if(modo==0) portc=0;
      if(modo==1) portc=1;
      if(modo==2) portc=2;}
}

Muchas gracias a todos otra vez
 

Adjuntos

  • 877.jpg
    877.jpg
    79.5 KB · Visitas: 57
Última edición por un moderador:
Hola jmth

Estuve probando el circuito que se mira en la imagen que adjuntaste.
Primero lo desarrollé en el ISIS de Proteus.
Al código que adjuntaste le agregue algunas notas. Esto es muy conveniente para que otras personas lo entiendan mejor. Faltan muchas notas en él.
Compile ese código y se lo asigné al PIC.


A tu diseño del circuito le hice algunas modificaciones como puedes verlo el la imagen que te adjunto.
Nota que todos los interruptores y el botón deben ser normalmente cerrador(NC).

Al Iniciar la simulación, el ascensor, está en el Piso #0 como se ve en el Display.
Si abres, en el grupo de Sensores De Llamada, el correspondiente al Piso #3 luego presionas el Botón, encenderá el LED Subiendo. El Botón debe quedar cerrado(NC).
Cierra, en el grupo de Sensores De Llamada, el correspondiente al Piso #3 y luego, en el grupo de Sensores De Posición, abre y cierra el correspondiente al Piso #3. el LED Subiendo se apagará y el Display Indicará 3 porque ahora el ascensor se localiza en el tercer piso.

Como que con tu programa la secuencia de movimiento de los interruptores y el botón es:
1- Todos cerrados. El ascensor está en el piso #0.
2- Se abre cualquier interruptor del grupo Sensores De Llamada. Dejándolo abierto.
3- Se presiona el botón. Dejándolo cerrado.
4- Se cierra el interruptor del grupo Sensores De Llamada. Que se había abierto.
5- se abre y se cierra en Sensores De Posición. Correspondiente al que movimos en el grupo de Sensores De Llamada.
6- El LED que había encendido se apaga pues el ascensor ya llegó a su destino. El Display indica el número de piso donde está ahora.

saludos
a sus ordenes
 

Adjuntos

  • Ascensor PIC16F877.jpg
    Ascensor PIC16F877.jpg
    331.2 KB · Visitas: 52
  • Ascensor PIC16F877.zip
    21.5 KB · Visitas: 46
Vaya, así es, muchas gracias, pero voy a tener que preguntar ¿A qué se debe tanta complejidad? No entiendo que sea necesario tener todo conectado de ésa forma, ya que antes con circuitos simples como el que tenia hecho funcionaba. Muchísimas gracias.
 
Hola jmth

Dices:
¿A qué se debe tanta complejidad?
No entiendo que sea necesario tener todo conectado de ésa forma,
ya que antes con circuitos simples como el que tenia hecho funcionaba.

Pues entonces regresa al proyecto cuando con circuitos simples como el que tenias hecho funcionaba.

saludos
a sus ordenes
 
Buenas noches, necesito hacer un elevador de 2 pisos, mi problema es no saber como detener el motor cuando se active un senSor, en la simulacion de Proteus ocupe 2 botones como si fuera el sensor y 2 botones para piso 1 y piso 2.
El motor lo controlo por medio de un puente h. mi principal probLEma es el codigo, si me podrian ayudar seria de gran ayuda.
Les adjunto los dos archivos. (la simulación es en Proteus)

Código:
#include <16f84A.h>

#fuses hs,nowdt

#use delay(clock=20M)

#use fast_io(a)

#use fast_io(b)

#include<lcd.c>



#define PB pin_a0

#define MZ pin_a1

#define S1 pin_a2

#define S2 pin_a3

#define SM1 pin_a4

#define SM2 pin_b3



void main()

{

int puls;

set_tris_a(0b01111);

set_tris_b(0b00000000);



while(1)

   {

   lcd_init();

   lcd_gotoxy(1,5);

         printf(lcd_putc,"ELEVADOR");

         delay_ms(4000);

         printf(lcd_putc,"\f");

    if (input(pin_a1)==1 && input(pin_a2)==1)

      {

         for (puls = 0; ;){

      if (input(pin_a3)==0){

         lcd_gotoxy(1,1);

         printf(lcd_putc,"SUBIENDO");

         delay_ms(4000);

         printf(lcd_putc,"\f");

      output_high(pin_a4);

      delay_ms(50);

          if (input(pin_a3)==1){

              puls++;

      }

      if (puls > 1){

      lcd_gotoxy(1,1);

         printf(lcd_putc,"PISO 2");

         delay_ms(4000);

         printf(lcd_putc,"\f");

      output_low(pin_a4); //subir

      delay_ms(10);

      puls=0;

      break;

     }

    }

   }

  }   

  else{

        if (input(pin_a0)==1 && input(pin_a1)==1)

      {

        for (puls = 0; ;){

      if (input(pin_a2)==0){

      lcd_gotoxy(1,1);

         printf(lcd_putc,"BAJANDO");

         delay_ms(4000);

         printf(lcd_putc,"\f");

      output_high(pin_b3);//bajar

      delay_ms(50);

          if (input(pin_a2)==1){

              puls++;

      }

      if (puls > 1){

      lcd_gotoxy(1,1);

         printf(lcd_putc,"PISO 1");

         delay_ms(4000);

         printf(lcd_putc,"\f");

      output_low(pin_b3); //bajar

      delay_ms(10);

      puls=0;

      break;

     }

    }

   }

  }

  }

}

}
 

Adjuntos

  • ELEVADOR.zip
    21.3 KB · Visitas: 11
No se si lo que planteas es un simple maquetaje, o es algo real, si es real de que capacidad en kilos estamos hablando, no se si sabes que los elevadores reales tienen un motor con freno.
Deberias dar más datos de tu proyecto
 
Hola, lo único que puedo aportar es que te deshagas de los delays, siendo que se trata de un sistema que tiene que ofrecer seguridad.
Si ocurre algún problema, y el programa está dentro de un delay, no podrá tomar acción hasta que salga de él.
Tienes dos maneras de estructurar el programa. O utilizas interrupciones, o bien, realizas un programa dinámico, en el cuál se ejecuta todo el programa miles de veces por segundo, y sólo habrá condiciones en dónde entrará para realizar acciones, todo ésto sin delays.
 
Atrás
Arriba