Carro de transferencia

47
Universidad Nacional de Misiones Facultad de Ingeniería Ingeniería Electrónica Técnicas Digitales 2 Control de carro de transferencia Autores: SCHERF, Pablo Jonathan TIMEZ, Francisco Gabriel Docentes Responsables: Ing. Juan Carlos Kairiyama Ing. FERNÁNDEZ, Guillermo A. Fecha de entrega: 27 de noviembre de 2014. Oberá, Misiones 2014

Transcript of Carro de transferencia

Page 1: Carro de transferencia

Universidad Nacional de Misiones

Facultad de Ingeniería

Ingeniería Electrónica

Técnicas Digitales 2

Control de carro de transferencia

Autores:

SCHERF, Pablo Jonathan

TIMEZ, Francisco Gabriel

Docentes Responsables:

Ing. Juan Carlos Kairiyama

Ing. FERNÁNDEZ, Guillermo A.

Fecha de entrega: 27 de noviembre de 2014.

Oberá, Misiones

2014

Page 2: Carro de transferencia
Page 3: Carro de transferencia

Introducción Como trabajo final de la cátedra Técnicas Digitales se plantea el diseño de un circuito

electrónico que requiera la aplicación de los conceptos adquiridos durante el cursado.

Como grupo se plantea realizar la automatización de un proceso industrial en una línea de

producción de ladrillos cerámicos.

En la línea de producción los adobes (ladrillos en verde) y ladrillos propiamente dicho, se

trasladan por medio de estantes y vagonetas que circulan sobre rieles. Estos rieles circulan en línea

recta de un lado al otro de un tinglado existiendo en cada extremo un carro de transferencia sobre el

cual son cargados los estantes y vagonetas a fin de ser transferidos de un riel a otro.

El circuito electrónico es diseñado para automatizar los procesos realizados por el carro de

transferencia. En el presente trabajo se procede a diseñar y construir solamente el circuito de control

dejando como tarea pendiente la implementación de dicha automatización.

Page 4: Carro de transferencia
Page 5: Carro de transferencia

Desarrollo

Detalles del proceso de la línea de producción A continuación se muestra un esquema de la línea de producción para así dar una perspectiva

del proyecto.

Barrera Infrarroja Sensor de distancia

1234567

EstanteVagonetaVagoneta Estante Estante Estante Estante

Referencia de posición Sensor inductivo

1

Estante

234567

EstanteVagonetaVagoneta

Estante Estante Estante

EstanteEstanteEstanteVagoneta

Vagoneta

1

2

Page 6: Carro de transferencia

Figura 1. Diagrama completo

En la Figura 1 se aprecia el proceso completo de la línea de producción. Entre los dos carros

de transferencia se encuentra el presecado (rieles “1” y “2”), secadero (rieles “3” y “4”), retorno (riel

“5”), horneado (riel “6”) y embalado (riel “7”).

Comenzamos la secuencia de la línea de producción mencionando que los ladrillos en verde

(salidos del proceso de extrusión) se encuentran cargados en los estantes que se ubican en el riel “1”

circulando en el sentido indicado por la flecha hasta el extremo donde se encuentra el carro “1”, este

tiene que trasladar dichos estantes de “1” a “2” para que retornen al otro extremo del tinglado, donde

son transferidos (con el carro “2”) a los rieles “3” y “4”. Una vez que los estantes atraviesan el

secadero el carro “1” los traslada al riel “5”. Luego en el otro extremo se transfieren los adobes

(ladrillos en verde) de un estante a una vagoneta y estas ingresan al horno. Cuando las vagonetas

atraviesan el horno deben nuevamente ser trasladadas, siendo movidas por el carro “1” del riel “6” al

riel “7”, donde aguarda el proceso de embalado.

A fin de contextualizar mejor la tarea que deberá controlar el circuito implementado se muestra

en la Figura 2 un diagrama que especifica los sentidos de circulación, rieles existentes, ubicación de

sensores, referencias de ubicación y carro de transferencia utilizado.

Barrera Infrarroja Sensor de distancia

1234567

EstanteVagonetaVagoneta Estante Estante Estante Estante

Referencia de posición Sensor inductivo

1

Figura 2. Diagrama representativo del proceso.

Sensores utilizados

Sensores de proximidad

Se considera la utilización de sensores inductivos de proximidad de la marca Schneider

Electric y modelo XS230SAPAL2 (Hoja de datos en el Anexo 4) los cuales tienen las características

básicas de trabajar con corriente continua, tensión entre 12 V y 24 V, protección contra tensión

inversa, salida discreta del tipo PNP y distancia de detección máxima de 22mm.

Page 7: Carro de transferencia

En el sistema de control se requerirán 7 sensores de este tipo. En detalle su utilización será, 4

sensores para la detección de estantes y vagonetas en las vías 1, 3, 4 y 6, 2 sensores para el brazo de

carga/descarga y un sensor más para testear el estado del electroimán.

Sensor de distancia

Se prevé la utilización de dos sensores de distancia de la marca Schneider Electric modelo

XUE5AA2NM12 el cual se alimenta con corriente continua de 24 V y entrega una salida de 4-20 mA

proporcional a la distancia medida, el mismo tiene una distancia de medición nominal de 6m. (Hoja

de datos del componente en el Anexo 5).

Los sensores son utilizados para la detección de la posición del carro (tomando la referencia

respecto a chapas fijas ubicadas a un lado de los rieles, se explica detalladamente en el funcionamiento

del código implementado) y para la medición de distancia del estante o vagoneta en los procesos de

carga y/o descarga.

Sensor tipo barrera

Se utiliza un sensor de este tipo para determinar la posición del carro a medida que este se

desplaza. Básicamente cuando el haz de la barrera es cortado genera una interrupción en el

microcontrolador aumentando un contador.

El sensor comercial considerado es 1A57HR el cual está compuesto por un diodo infrarrojo y

un fototransistor. (Hoja de datos reducida Anexo 6)

Variador de velocidad YASKAWA J7mini El mismo puede ser controlado mediante un lazo de corriente de 4 a 20mA, entre otras

opciones, pero esta fue la elegida por su practicidad, por otro lado permite la inversión de marcha

mediante dos entradas digitales que fueron implementadas mediante un opto acoplador que se

acciona con el microcontrolador directamente sin necesidad de acoplar al mismo una etapa de

potencia.

Este variador de velocidad posee varias funciones de las cuales se utiliza principalmente,

encendido y apagado en rampa y bloqueo temporal de rotor el cual es utilizado para posicionar el

carro en su correcta posición.

Hoja de datos y manual de instrucciones puede descargarse de la siguiente página web

https://www.yaskawa.com/pycprd/download/home#tab1.

Montaje del circuito Cabe mencionar que el circuito de control está compuesto por dos placas, en una se encuentra

la pantalla y los botones de configuración y en la otra el microcontrolador con las entradas y salidas

de control. Ambas placas han sido diseñadas con ayuda del software Eagle.

Los pasos para la construcción de la placa fueron:

Diseño del circuito esquemático.

Diseño del circuito en PCB.

Impresión en papel fotográfico.

Planchado sobre la placa.

Remoción del papel y restos de todo tipo.

Revisión de pistas (las pistas con defectos fueron remarcadas o trazadas con marcador

permanente).

Page 8: Carro de transferencia

Quemado, colocando la placa en ácido (Cloruro Férrico).

Perforación de los orificios.

Pintado con flux.

Secado.

Montaje y soldado de componentes.

Placa de pantalla

Figura 3. Layout de la pantalla y botonera.

En la Figura 3 se muestra un Layout del circuito. Se utiliza una pantalla de 2x16 con 5 botones

que tienen una conexión con una entrada analógica del microcontrolador, con las distintas resistencias

se dan las distintas tensiones a la que responde la entrada mencionada. La placa cuenta con un sexto

botón que se comunica con el pin RB1 del microcontrolador generando una interrupción. Además de

aprecia un resistor variable utilizado para regular el contraste de la pantalla.

Bajo la pantalla se encuentran los pines de conexión del circuito.

En cuanto al proceso de construcción de la misma, no se presentaron mayores inconvenientes

ya que es una placa sencilla en la Figura 4 y ¡Error! No se encuentra el origen de la referencia. se

aprecian fotos de la misma. En el Anexo 1 se puede encontrar el circuito esquemático de dicha placa.

Figura 4. Frente de la placa.

Page 9: Carro de transferencia

Placa de microcontrolador

Figura 5. Layout de la placa principal.

En la placa de la Figura 5 se aprecia el Layout de los componentes. En términos generales se

aprecia en la parte superior, la entrada de alimentación del sistema; a la derecha las salidas (relés); en

la parte inferior las entradas de los sensores digitales; y a la izquierda, en la parte superior se

encuentran las entradas analógicas (4-20mA), en la mitad de la placa se encuentran los pines de

conexión con la pantalla y en la parte inferior las salidas de control del variador. El microcontrolador

está ubicado cercano al centro del circuito.

En cuanto al proceso de construcción destacamos los siguientes ítems:

Page 10: Carro de transferencia

El planchado sobre la placa se debió realizar dos veces debido a que se detectaron muchos

defectos. A pesar de ello se debió retocar manualmente todos los bordes de la placa, incluyendo

dos pistas casi completas.

Las distancias entre los relés fueron insuficientes en algunos lugares de modo que se tuvo que

forzar para su colocación.

La distancia entre las borneras y leds en la parte inferior de la placa también fueron

insuficientes, por lo que se tuvo que doblar los pines de los leds.

En el diseño en PCB de la placa principal no se incluyeron los pines de alimentación de la

placa de la pantalla, los cuales se colocaron al momento de realizar las pruebas.

El circuito de la pantalla con cuenta con un capacitor en la alimentación para eliminar o

disminuir el ruido.

El resultado de la construcción del circuito se aprecia en las dos fotos siguientes

Figura 6. Frente de la placa.

Page 11: Carro de transferencia

Figura 7. Vista trasera de la placa.

Cálculos

Filtro pasa bajo

1 110,6

2 2 1,5 10f Hz

RC k F

(1)

Entrada de 4 a 20mA

La entrada es sobre una resistencia de 100ohm, por lo tanto se tienen tensiones de 0,4 y 2V.

Entonces se tienen las siguientes ecuaciones de un amplificador de diferencia.

Page 12: Carro de transferencia

2

1

o

RV V V

R (2)

21

1 11 2

2 22

1

2

5 5 1

0,4

o

oo o

oo

RV

R VV V V V

R VV

R

(3)

Entonces

22 1 1 2

1

52,5 2,5 3,3 8, 2

2

R VR R R k R k

R V

(4)

Salida de 4 a 20mA

La tensión de salida máxima será de 5V por lo tanto la resistencia para el lazo de corriente

será:

5250

0,02

VR

A

(5)

Resistencia de los leds

La corriente se calculó baja por que se pensaba utilizar leds de alta luminosidad.

5 23

1

V VR mA

k

(6)

Para leds convencionales será.

5 29

330

V VR mA

(7)

Programación del microcontrolador En lo que respecta a la programación del micro se realizó la misma sobre un PIC18F4550, el

cual no se pudo cumplimentar dado que el mismo no respondía adecuadamente, específicamente

ignoraba las entradas en los pines RC4 y RC5, como un intento de solucionar el inconveniente se

grabó el programa ya realizado bajo este micro en un PIC18F4585 que se tenía a disposición y el

mismo funciono correctamente, analizando un poco más se vio que el 4550 en esos pines posee la

comunicación USB y por más que la misma se deshabilite no solucionaba el inconveniente, el 4585

no posee comunicación USB por lo tanto no presento estos problemas.

Entrando en detalle con la lógica del programa se detallan presentan los siguientes diagramas

de flujo.

Page 13: Carro de transferencia

Figura 8. Diagrama de flujo del programa.

En el caso de la función principal, vemos que en la misma se testean los sensores que indican

la presencia de estantes/vagonetas en los carriles, se necesita testear con un orden de prioridad que

está en evidencia en el diagrama de flujo, la mayor prioridad se encuentra a la salida del horno, por

lo tanto este es el primero en atenderse, luego el carril 1 que es la salida del pre secado y por último

los carriles del secadero dado que estos pueden ser de mayor espera, por otro lado no es difícil

cambiar el orden de prioridad en el caso de que el régimen de prioridades no funcione.

Como se puede ver además los registros de origen y destino son registros globales que

contienen justamente la dirección de origen y destino de los estantes; luego se invoca a la función

tarea que se detalla a continuación.

Page 14: Carro de transferencia

Figura 9. Diagrama de flujo de la función tarea.

La función tarea determina que tarea debe realizarse, si el carro debe moverse, quedarse en la

posición actual o volver a alguna posición en particular, y para esto se vale de las funciones

movimiento y carga/descarga, que se detallaran en a continuación.

La función movimiento realiza el justamente movimiento del carro a la posición deseada,

teniendo en cuenta todas las cuestiones pertinentes, como ser el accionamiento del electroimán,

control de velocidad, frenado del carro, corroboración de posición, realiza las operaciones necesarias

para que el carro quede posicionado en el lugar correcto. Para esto se vale da funciones de frenado,

determinar posición, electroimán, reubicar; cada una con una función específica.

Otra función importante es carga/descarga; la misma tiene la tarea de realizar la carga o

descarga de un estante o vagoneta, teniendo en cuenta el accionamiento del brazo, lectura de los

sensores de distancia del carro al estante, y los tiempos máximos de funcionamiento del sistema de

carga/descarga.

Page 15: Carro de transferencia

Figura 10. Diagrama de flujo de la función movimiento.

Figura 11. Diagrama de flujo de la función carga/descarga.

Movimiento(accion)

Accion==0

Retorno

Electroiman(0)

Accion=accion*3-1Marcha=1

Ninterrup<accion Cutil=100%

Frenado

Detectar_posicon

Electroiman(1)

Retorno

Carga/Descarga

Posicion==2||==5||==7

Distancia < 270

Descarga

Posicion==1||==3||==4||==6

Distancia > 700

Descarga

Retorno

Page 16: Carro de transferencia

Puesta en funcionamiento Para la puesta en funcionamiento del sistema es necesario setear el preset que regula la

mínima corriente por el lazo de corriente en mismo se setea cerrando el lazo con un amperímetro y

regulando el mismo hasta llegar a los 4 mA con una entrada PWM con ciclo útil de 0%.

Además en necesario setear las distancias que medirá el sensor que establece la posición del

carro, el mismo se realiza entrando al menú de configuración, luego posicionando el carro en el

lugar correspondiente y presionando un botón en el menú para guardar los valores.

Por ultimo para poner en funcionamiento es necesario poner el registro tarea en OK y setear

la posición actual del carro, para el correcto funcionamiento.

Conclusiones El desarrollo del proyecto nos da una experiencia más que nada de aprendizaje en cuanto al

diseño y construcción de circuitos de control de un proceso industrial, considerando las protecciones

y métodos de comunicación entre los sensores de uso industrial.

El variador de frecuencia utilizado nos trajo algunos inconvenientes en el control debido a

sus configuraciones, luego de resetear las configuraciones de fábrica y volver a configurarlo

respecto al método de control utilizado el mismo respondió correctamente.

Mejoras a implementar en el código

Determinar en qué proceso se produce un error y mostrar en pantalla. Actualmente solo se

visualiza el mensaje de error pero no se conoce de donde proviene el mismo.

En el reseteo del programa hay que introducir algunas mejoras para el reinicio de la tarea como

ser el testeo de existencia de carga en el carro y realizar la acción correspondiente.

Incluir en la configuración la selección de tipo de entrada analógica, esta puede ser de 0-20mA

o de 4-20mA.

Autocalibración del PWM cuando se cambia la salida de 4-20mA a 0-20mA.

Mejoras a implementar en la placa

Dos cosas muy importantes

Aislar las tierras de los relés y optoacopladores del resto del circuito. Colocando

alimentaciones independientes.

Colocar una etapa de amplificación de a la salida de los optoacopladores.

Otros aspectos a tener en cuenta

Revisar correctamente las dimensiones de los elementos utilizados.

Utilizar torres hembra para la programación en circuito. Las torres tipo macho facilitan la

entrada de ruido, generalmente por contacto.

Dejar espacio para colocar los nombres de los bornes de entrada y de salida.

Colocar protecciones para las entradas analógicas.

Page 17: Carro de transferencia

Anexo 1 Esquema circuital utilizado

Esquema de conexión del microcontrolador con sus correspondientes entradas y salidas,

alimentación del sistema, capacitores de estabilización de tensión, botón de reset, pines de salida

del LCD, pines de programación en circuito y conexión del cristal externo.

Entradas de sensores al sistema

Conversión corriente a tensión. Entrada analógica.

Page 18: Carro de transferencia

Entradas digitales del sistema.

Page 19: Carro de transferencia

Etapa de conversión PWM a salida de corriente. Con el jumper que se aprecia el la figura se

puede elegir el tipo de salida 4-20mA o 0-20mA.

Salidas digitales a reles.

Conexiones entre el micro y las salidas conectadas al variador de frecuencia.

Page 20: Carro de transferencia

Esquematico de la placa en donde se encuentra la pantalla

Page 21: Carro de transferencia

Anexo 2 Componentes utilizados

Elemento Valor Componente Encapsulado Librería Cantidad

Placa microcontrolador

C1 10u C2.5/5 C2.5-5 capacitor-wima 1

C2, C4, C6,

C9

100n C2.5/5 C2.5-5 capacitor-wima 4

C3, C5 27p C-EU025-025X050 C025-

025X050

rcl 2

C7, C8 470u CPOL-EUE3.5-10 E3,5-10 resistor 2

D1, D2 5.1 ZENER-

DIODEZD-5

ZDIO-5 diode 2

D3, D19-D25 1N4004 1N4004 DO41-10 diode 8

D4-D18 HLMP6 HLMP6 HLMP6 Diode 15

IC1, IC2 LM358N LM358N DIL08 linear 2

IC3 PIC18F4550_40 PIC18F4550_40 DIL40 microchip 1

JP1, JP5 JP1E JP1 jumper 2

JP2, JP3 JP4E JP4 jumper 2

JP4 JP2E JP2 jumper 1

K1-K7 G5L G5L G5LE relay 7

OK1 ILD610 ILD610 DIL08 optocoupler 1

OK2-OK5 ILQ1 ILQ1 DIL16 optocoupler 4

Q1 8M CRYSTALHC49S HC49/S crystal 1

R1 1k5 R-EU_0207/7 0207/7 rcl 1

R2, R17, R26-

R30, R53-R56

10k TRIM_EU-RJ9W RJ9W pot 11

R3, R4, R7,

R8

3k3 R-EU_0207/7 0207/7 rcl 4

R5, R6, R12 100 R-EU_0207/7 0207/7 rcl 3

R9-R11, R15 8k2 R-EU_0207/7 0207/7 rcl 4

R13, R14,

R46-R52

330 R0204/7 0204/7 eagle-ltspice 9

R16 150 R-EU_0207/7 0207/7 rcl 1

R18-R38 1k R-EU_0207/7 0207/7 rcl 16

R39-R45 470 R-EU_0207/7 0207/7 rcl 7

S1 PVA1R PVA1R PVA1R switch-misc 1

T1 BC337 BC337 TO92 transistor 1

X1 W237-04P W237-4P con-wago-508 1

X2-X8, X10-

X13

W237-02P W237-132 con-wago-508 11

X9, X14-X20 W237-3E W237-3E con-wago-508 8

Placa pantalla

BUTTON PVA1R PVA1R PVA1R switch-misc 6

R1, R6, R7 10k R-TRIMM64W RTRIM64W rcl 3

Page 22: Carro de transferencia

R2 2K7 R-EU_0207/7 0207/7 rcl 1

R3 3K9 R-EU_0207/7 0207/7 rcl 1

R4, R5 8k2 R-EU_0207/7 0207/7 rcl 2

DIS1 TUXGR_16X2_

R2

TUXGR_16X2_R2 TUXGR_16X

2_R2

display-lcd 1

JP1, JP2 JP4E JP4 jumper 2

JP3 JP1Q JP1 jumper 1

Page 23: Carro de transferencia

Anexo 3 El código es el siguiente:

#include <18F4550.h>

#device adc=10

#FUSES NOWDT //No Watch Dog Timer

#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale

#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for

PCD)

#FUSES NOBROWNOUT //No brownout reset

#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 (Legacy mode)

#use delay(clock=8000000)

#use fast_io(A)

#use fast_io(B)

#use fast_io(C)

#use fast_io(D)

#use fast_io(E)

// Conversor ADC -----------------------------------------------------------

#byte ADCON0 = 0xFC2 // Registro de config. del ADC.

#byte ADCON1 = 0xFC1 // Registro de config. del ADC.

#byte ADCON2 = 0xFC0 // Registro de config. del ADC.

// Puertos -----------------------------------------------------------------

// Puerto A -----------------------------------------------------------

#byte TRISA = 0xF92 // Registro de config. del puerto A.

#byte LATA = 0xF89

#byte PORTA = 0xF80 // Registro de acceso al puerto A.

#bit Test_posicion = PORTA.0 // Entrada analogica. (Ubicacion del carro)

#bit Test_distancia = PORTA.1 // Entrada analogica. (Distancia del

estante/vagoneta)

#bit Botones = PORTA.2 // Entrada analogica. (Botones de comando)

//#bit LCD = PORTA.3

//#bit LCD = PORTA.4

//#bit LCD = PORTA.5

//6 y 7 para XTAL.

// Puerto B ------------------------------------------------------------

#byte TRISB = 0xF93 // Registro de config. del puerto B.

#byte LATB = 0xF8A

#byte PORTB = 0xF81 // Registro de acceso al puerto B.

#bit Barrera = PORTB.0 // Entrada. Interrupcion.

#bit menu = PORTB.1 // Entrada. Interrupcion.

#bit Puerta3 = PORTB.2 // Salida (Extiende el brazo de carga/descarga)

#bit A_electroiman = PORTB.3 // Salida (Contrae el brazo de carga/descarga)

#bit ext_brazo = PORTB.4 // Entrada (Sensor mas alejado de las vias) (Alto

cuando el haz se corta)

#bit enc_brazo = PORTB.5 // Entrada (Sensor mas cercano a la via.) (Alto

cuando el haz se corta)

//#bit = PORTB.6 // Entrada (Evalua el estado del electroiman)

//#bit = PORTB.7 // Salida (Acciona el electroiman)

// Puerto C ---------------------------------------------------------

#byte TRISC = 0xF94 // Registro de config. del puerto C.

#byte LATC = 0xF8B

#byte PORTC = 0xF82 // Registro de acceso al puerto C.

#bit derecha = PORTC.0 // Salida. (Encendido/apagado del motor)

Page 24: Carro de transferencia

#bit reversa = PORTC.1 // Salida. (Sentido de giro del motor)

//#bit CCP = PORTC.2 //CCP

//#bit VUSB = PORTC.3 //USB?????

#bit Carril4 = PORTC.4 // Entrada magnetico Carril 4.

#bit Carril6 = PORTC.5 // Entrada magnetico Carril 5.

#bit Test_electroiman = PORTC.6

#bit sensor1 = PORTC.7

// Puerto D ----------------------------------------------------------

#byte TRISD = 0xF95 // Registro de config. del puerto D.

#byte LATD = 0xF8C

#byte PORTD = 0xF83 // Registro de acceso al puerto D.

//#bit Libre = PORTD.0

//#bit Libre = PORTD.1

#bit Carril1 = PORTD.2 // Entrada magnetico Carril 1.

#bit Carril3 = PORTD.3 // Entrada magnetico Carril 3.

#bit sensor2 = PORTD.4

#bit Alarma = PORTD.5 // Salida Señal puerta 1.

#bit Puerta1 = PORTD.6 // Salida Señal puerta 2.

#bit Puerta2 = PORTD.7 // Salida Señal puerta 3.

// Puerto E -----------------------------------------------------------

#byte TRISE = 0xF96 // Registro de config. del puerto E.

#byte LATE = 0xFD

#byte PORTE = 0xF84 // Registro de acceso al puerto E.

//#bit LCD = PORTE.0 //

//#bit LCD = PORTE.1 //

//#bit LCD = PORTE.2 //

//#bit MCLR = PORTE.3 //Master clear.

#byte UCON = 0xF6D

#bit USBEN = 0xF6D.3

#define LCD_RS PIN_A3

#define LCD_E PIN_A4

#define LCD_DB4 PIN_A5

#define LCD_DB5 PIN_E0

#define LCD_DB6 PIN_E1

#define LCD_DB7 PIN_E2

// Flex_lcd.c

//#define LCD_DB4 PIN_B4

//#define LCD_DB5 PIN_B5

//#define LCD_DB6 PIN_B6

//#define LCD_DB7 PIN_B7

//#define LCD_RS PIN_C0

//#define LCD_RW PIN_C1

//#define LCD_E PIN_C2

// If you only want a 6-pin interface to your LCD, then

// connect the R/W pin on the LCD to ground, and comment

// out the following line.

//#define USE_LCD_RW 1

//========================================

#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines (Cantidad de líneas del

Display)

#define lcd_line_two 0x40 // LCD RAM address for the 2nd line

byte const LCD_INIT_STRING[4]={0x20 | (lcd_type << 2), 0xc, 1,6};

// Func set: 4-bit, 2 lines, 5x8 dots // Display on // Clear display //

Increment cursor

//-------------------------------------

Page 25: Carro de transferencia

void lcd_send_nibble(int8 nibble)

{

// Note: !! converts an integer expression

// to a boolean (1 or 0).

output_bit(LCD_DB4, !!(nibble & 1));

output_bit(LCD_DB5, !!(nibble & 2));

output_bit(LCD_DB6, !!(nibble & 4));

output_bit(LCD_DB7, !!(nibble & 8));

delay_cycles(1);

output_high(LCD_E);

delay_us(2);

output_low(LCD_E);

}

//----------------------------------------

// Send a byte to the LCD.

void lcd_send_byte(int8 address, int8 n)

{

output_low(LCD_RS);

if(address)

output_high(LCD_RS);

else

output_low(LCD_RS);

delay_cycles(1);

output_low(LCD_E);

lcd_send_nibble(n >> 4);

lcd_send_nibble(n & 0xf);

}

//----------------------------

void lcd_init(void)

{

int8 i;

output_low(LCD_RS);

output_low(LCD_E);

delay_ms(15);

for(i=0 ;i < 3; i++)

{

lcd_send_nibble(0x03);

delay_ms(5);

}

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)

{

lcd_send_byte(0, LCD_INIT_STRING[i]);

}

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)

{

int8 address;

if(y != 1)

address = lcd_line_two;

else

address=0;

Page 26: Carro de transferencia

address += x-1;

lcd_send_byte(0, 0x80 | address);

}

//-----------------------------

void lcd_putc(char c)

{

switch(c)

{

case '\h':

lcd_send_byte(0,2);

delay_ms(2);

break;

case '\f':

lcd_send_byte(0,1);

delay_ms(2);

break;

case '\n':

lcd_gotoxy(1,2);

break;

case '\b':

lcd_send_byte(0,0x10);

break;

default:

lcd_send_byte(1,c);

break;

}

}

//------------------------------

void lcd_setcursor_vb(short visible, short blink) {

lcd_send_byte(0, 0xC|(visible<<1)|blink);

}

//FIN Flex_LCD

//Constantes del programa.

#define cutilmax 500

#define T_out_brazo 2000

#define T_blink 100

#define T_sensado 300

#define T_puerta 0

#define EEPROM_pos 0xF00020

#rom int16 EEPROM_pos={000,279,310,350,400,471,573,729}

#define tol_pos 50

// INICIALIZACION DE VARIABLES ----------------------------------------------------

--------

int giro=0;

int16 cutil, Lectura;

int16 Lectura_adc[10]={0,0,0,0,0,0,0,0,0,0};

int* info;

char donde[30];

int Ninterrupts = 0;

int informacion[9]={0,0,0,0,0,0,0,0,0};

int16 Set_pos2[8];

/*

informacion[0] = Resultado de la tarea: erronea "0", correcta "1".

informacion[1] = Estado: sin carga "0", movimiento de 1 a 2 "1", movimiento de 3 a

5 "2", movimiento de 4 a 5 "3", movimiento de 6 a 7 "4"

Page 27: Carro de transferencia

informacion[2] = Pocicion actual: 1, 2, 3, 4, 5, 6 y 7.

informacion[3] = Origen: 1, 2, 3, 4, 5, 6 y 7.

informacion[4] = Destino: 1, 2, 3, 4, 5, 6 y 7.

informacion[5] = Menu: 0 y 1.

informacion[6] = Alarma: 0 1. Encendido 0 y Apagado 1

informacion[7] = Calibracion de frenado: 0 - 100; Ver funcion frenado.

informacion[8] = Frecuencia minima. 0 - 60.

*/

// INICIALIZACION DE FUNCIONES ----------------------------------------------------

--

void menu_config(void); //Listo.

void set_pos(void);

char leer_pulsadores(void); //Listo.

void guardar_EEPROM (void); //Listo.

void tarea(void);

void movimiento (int);

void SecCD (void);

void descargar (void);

void cargar (void);

void contraer (void);

void extender (void);

int DetPosicion (void);

void reubicar_en (int);

void electroiman (int);

void calibrar (void);

void frenado (void);

int16 read_adc_prom(int cant);

#INT_EXT

void EXT_isr(void)

{

delay_ms(30);

if(Barrera==1)

Ninterrupts = Ninterrupts+1;

if (Ninterrupts != 0 && (Ninterrupts%3)==0) // Actualizacion de la

posicion actual.

{

if(giro==0)

*(info+2)=*(info+2)+1;

else

*(info+2)=*(info+2)-1;

guardar_EEPROM();

}

return;

}

#int_EXT1

void EXT1_isr(void)

{

delay_ms(30);

if(menu==0)

*(info+5)=1;

return;

}

// PRORAMA PRINCIPAL --------------------------------------------------------------

--------

void main()

{

USBEN=0;

setup_adc(ADC_CLOCK_DIV_64|ADC_TAD_MUL_16);

setup_adc_ports(AN0_TO_AN2|VSS_VDD);

set_tris_a(0b00000111); // Configuracion: Puerto A

PORTA = 0x00; // Inicializacion: puerto A.

set_tris_b(0b11000011); // Configuracion: Puerto B

Page 28: Carro de transferencia

PORTB = 0x00; // Inicializacion: puerto B.

set_tris_c(0b11110000); // Configuracion: Puerto C

PORTC = 0x00; // Inicializacion: puerto C.

set_tris_d(0b00011111); // Configuracion: Puerto D

PORTD = 0x00; // Inicializacion: puerto D.

set_tris_e(0b00001000); // Configuracion: Puerto E

PORTE = 0x00; // Inicializacion: puerto E.

lcd_init();

//Cargar el vector pos de la EEPROM.

for(int i=0;i<8;i++)

{

Set_pos2[i] = read_eeprom(EEPROM_pos+2*i+1);

Set_pos2[i]*=256;

Set_pos2[i] |= read_eeprom(EEPROM_pos+2*i);

}

// CONFIGURACION DE LA INTERRUPCION

enable_interrupts(int_EXT);

ext_int_edge( 0, L_TO_H);

enable_interrupts(int_EXT1);

ext_int_edge( 1, H_TO_L);

enable_interrupts(global);

// DIRECCIONAMIENTO DEL PUNTERO

info = &informacion;

*(info+7)=13;

// CCP1 en modo PWM

setup_ccp1(CCP_PWM);

set_pwm1_duty(0);

derecha=0;

reversa=0;

setup_timer_2(T2_DIV_BY_16,125,1); //1008Hz

printf(lcd_putc,"\fBienvenido a \n CarroMatic 2014");

delay_ms(2000); //2000

menu_config();

while(TRUE)

{

lcd_setcursor_vb(0,0);

if(*info==2)

*info=1;

if(*(info+5)==1)

menu_config();

printf(lcd_putc,"\hTesteando Vias... ");

lcd_gotoxy(1,2);

printf(lcd_putc," 1 2 3 4 5 6 7 ");

//Testeo de las vias, Hay/No Hay Estante.

lcd_setcursor_vb(0,1);

lcd_gotoxy(2,2);

delay_ms(T_blink);

if(*info==0)

printf(lcd_putc,"\fERROR!!!!! ");

lcd_gotoxy(12,2);

delay_ms(T_blink);

if(Carril6==1 && *info==1)

{

delay_ms(T_sensado);

if(Carril6==1)

{

*(info+3)=6;

*(info+4)=7;

tarea();

*info=2;

}

}

if(Carril1==1 && *info==1)

{

delay_ms(T_sensado);

Page 29: Carro de transferencia

if(Carril1==1)

{

*(info+3)=1;

*(info+4)=2;

tarea();

*info=2;

}

}

lcd_gotoxy(6,2);

delay_ms(T_blink);

if(Carril3==1 && *info==1)

{

delay_ms(T_sensado);

if(Carril3==1)

{

*(info+3)=3;

*(info+4)=5;

tarea();

*info=2;

}

}

lcd_gotoxy(8,2);

delay_ms(T_blink);

if(Carril4==1 && *info==1)

{

delay_ms(T_sensado);

if(Carril4==1)

{

*(info+3)=4;

*(info+4)=5;

tarea();

*info=2;

}

}

}

}

// DECLARACION DE FUNCIONES--------------------------------------------------------

--------------

//Menu de configuracion del vector informacion.

void menu_config(void)

{

disable_interrupts(int_EXT1);

char botone;

int caso=0;

int informacion_gost[8];

int* infog;

infog = &informacion_gost;

for(int i=0;i<8;i++)

informacion_gost[i]=informacion[i];

while(menu==0)delay_ms(20);

while(menu==1)

{

printf(lcd_putc,"\hConfiguracion ");

botone = leer_pulsadores();

delay_ms(50);

if(botone==leer_pulsadores());

{

if(botone=='R')

caso++;

else if(botone=='L')

caso--;

switch(caso)

{

Page 30: Carro de transferencia

case 0: //informacion[0] = Resultado de la tarea: erronea "0",

correcta "1".

{

lcd_gotoxy(1,2);

if(botone=='U'||botone=='D')

if(*infog==0) *infog=1;

else *infog=0;

if(*infog==0)

printf(lcd_putc,"Tarea: Error ");

else

printf(lcd_putc,"Tarea: OK ");

delay_ms(50); break;

}

case 1: //informacion[1] = Estado: sin carga "0", movimiento de

1 a 2 "1",de 3 a 5 "2",de 4 a 5 "3",de 6 a 7 "4"

{

lcd_gotoxy(1,2);

if(botone=='U')

*(infog+1) = *(infog+1)+1;

else if(botone=='D')

*(infog+1) = *(infog+1)-1;

switch(*(infog+1))

{

case 0:

{printf(lcd_putc,"Estado:Sin Carga"); break;}

case 1:

{printf(lcd_putc,"Estado: 1 a 2 "); break;}

case 2:

{printf(lcd_putc,"Estado: 3 a 5 "); break;}

case 3:

{printf(lcd_putc,"Estado: 4 a 5 "); break;}

case 4:

{printf(lcd_putc,"Estado: 6 a 7 "); break;}

case -1:

{*(infog+1)=4; break;}

case 5:

{*(infog+1)=0; break;}

};

delay_ms(50); break;

}

case 2: //informacion[2] = Posicion actual: 1, 2, 3, 4, 5, 6 y

7.

{

lcd_gotoxy(1,2);

if(botone=='U') *(infog+2) = *(infog+2)+1;

else if(botone=='D') *(infog+2) = *(infog+2)-1;

switch(*(infog+2))

{

case 0:

{*(infog+2)=7; break;}

case 8:

{*(infog+2)=1; break;}

default:

{printf(lcd_putc,"Pos Actual: %d ",*(infog+2));

break;}

};

delay_ms(50); break;

}

case 3: //informacion[3] = Origen: 1, 2, 3, 4, 5, 6 y 7.

{

lcd_gotoxy(1,2);

if(botone=='U') *(infog+3) = *(infog+3)+1;

else if(botone=='D') *(infog+3) = *(infog+3)-1;

switch(*(infog+3))

{

Page 31: Carro de transferencia

case 0:

{*(infog+3)=7; break;}

case 8:

{*(infog+3)=1; break;}

default:

{printf(lcd_putc,"Origen: %d ",*(infog+3));

break;}

};

delay_ms(50); break;

}

case 4: //informacion[4] = Destino: 1, 2, 3, 4, 5, 6 y 7.

{

lcd_gotoxy(1,2);

if(botone=='U') *(infog+4) = *(infog+4)+1;

else if(botone=='D') *(infog+4) = *(infog+4)-1;

switch(*(infog+4))

{

case 0:

{*(infog+4)=7; break;}

case 8:

{*(infog+4)=1; break;}

default:

{printf(lcd_putc,"Destino: %d ",*(infog+4));

break;}

};

delay_ms(50); break;

}

case 6: //informacion[6] = Alarma: 0 y 1. Encendido 0 y

Apagado 1

{

lcd_gotoxy(1,2);

if(botone=='U'||botone=='D')

if(*(infog+6)==0)

*(infog+6)=1;

else

*(infog+6)=0;

if(*(infog+6)==0)

printf(lcd_putc,"Alarma: Apagada ");

else

printf(lcd_putc,"Alarma:Encendida");

delay_ms(50); break;

}

case 7: //informacion[7] = Calibracion de frenado: 0 - 100;

Ver funcion frenado.

{

lcd_gotoxy(1,2);

if(botone=='U') *(infog+7) = *(infog+7)+1;

else if(botone=='D') *(infog+7) = *(infog+7)-1;

switch(*(infog+7))

{

case -1:

{*(infog+7)=101; break;}

case 101:

{*(infog+7)=0; break;}

default:

{printf(lcd_putc,"Frenado: %d ",*(infog+7));

break;}

};

delay_ms(50); break;

}

case 8: //informacion[8] = Frecuencia minima. 0 - 60.

{

lcd_gotoxy(1,2);

if(botone=='U') *(infog+8) = *(infog+8)+1;

else if(botone=='D') *(infog+8) = *(infog+8)-1;

Page 32: Carro de transferencia

switch(*(infog+8))

{

case -1:

{*(infog+8)=60; break;}

case 61:

{*(infog+8)=0; break;}

default:

{printf(lcd_putc,"Frec Min: %d ",*(infog+8));

break;}

};

delay_ms(50); break;

}

case 9: //Set_pos[2] = Posicion actual: 1, 2, 3, 4, 5, 6 y 7.

{

lcd_gotoxy(1,2);

printf(lcd_putc,"Set_pos ");

if(botone=='S')

set_pos();

delay_ms(50); break;

}

case -1:

{caso = 9; break;}

case 10:

{caso = 0; break;}

};

}

}

for(i=0;i<sizeof(informacion);i++)

informacion[i]=informacion_gost[i];

guardar_EEPROM();

*(info+5)=0;

clear_interrupt(int_EXT1);

do delay_ms(20);while(menu==0);

enable_interrupts(int_EXT1);

}

//Menu capa Set_pos.

void set_pos(void)

{

int po=0;

char botone2;

int16 value;

while(leer_pulsadores()!='S')

{

set_adc_channel(0);

delay_ms(30);

value = read_adc_prom(10);

lcd_gotoxy(1,1);

printf(lcd_putc,"\hPos %d viejo %li \nActual: %li

",po,Set_pos2[po],value);

botone2=leer_pulsadores();

delay_ms(50);

if(botone2==leer_pulsadores());

{

switch(botone2)

{

case 'R':

{

po++;

if(po==8)

po=0;

break;

}

case 'L':

{

Page 33: Carro de transferencia

po--;

if(po==-1)

po=8;

break;

}

case 'U':

{

Set_pos2[po]=value;

break;

}

case 'D':

{

Set_pos2[po] = read_eeprom(EEPROM_pos+2*po+1);

Set_pos2[po]*=256;

Set_pos2[po] |= read_eeprom(EEPROM_pos+2*po);

break;

}

}

}

}

for(int j=0;j<8;j++)

{

write_eeprom(EEPROM_pos+2*j,Set_pos2[j]);

Set_pos2[j]/=256;

write_eeprom(EEPROM_pos+2*j+1,Set_pos2[j]);

Set_pos2[j] = read_eeprom(EEPROM_pos+2*j+1);

Set_pos2[j]*=256;

Set_pos2[j] |= read_eeprom(EEPROM_pos+2*j);

}

return;

}

//Lee los pulsadores.

char leer_pulsadores(void)

{

int16 val;

set_adc_channel(2);

delay_ms(10);

val = read_adc();

if(val>900)

return 'N';

else if(val>700)

return 'S';

else if(val>500)

return 'L';

else if(val>300)

return 'D';

else if(val>100)

return 'U';

else

return 'R';

}

//Realiza la copia del vector información a la memoria EEPROM del micro.

void guardar_EEPROM (void)

{

for(int i=0;i<sizeof(informacion);i++)

write_eeprom(i,informacion[i]);

}

// REALIZA UNA TAREA COMPLETA. MOVIMIENTO-CARGA-MOVIMIENTO-DESCARGA.

// Analiza la posicion del carro y con respecto al destino que tiene en el vector

de informacion.

// Si son diferentes, evalua el sentido de movimiento y procede a llamar a la

funcion que lleva a

Page 34: Carro de transferencia

// cabo el desplazamiento.

// Estados afectados: Resultado de la tarea. Posicion actual.

void tarea (void) //Listo

{

int accion;

lcd_setcursor_vb(0,0);

//Determinacion de sentido de giro.

if(*(info+3) > *(info+2))

{

giro=0;

accion = *(info+3) - *(info+2); // accion = origen - posicion

}

else

{

giro=1;

accion = *(info+2) - *(info+3); // accion = origen - posicion

}

sprintf(donde,"Origen: Via %d ",*(info+3));

movimiento(accion);

if(*info==0)

{*(info+6)==0;return;}

else

SecCD(); //Depurar

//Determinacion de sentido de giro.

if(*(info+4) > *(info+2))

{

giro=0;

accion = *(info+4) - *(info+2); // accion = origen - posicion

}

else

{

giro=1;

accion = *(info+2) - *(info+4); // accion = origen - posicion

}

sprintf(donde,"Destino: Via %d ",*(info+4));

movimiento(accion);

if(*info==0)

{*(info+6)==0;return;}

else

SecCD();

lcd_setcursor_vb(0,1);

return;

}

// EVALUA NECESIDAD DE MOVIMIENTO Y SENTIDO DE AVANCE

// Analiza la posicion del carro y con respecto al destino que tiene en el vector

de informacion.

// Si son diferentes, evalua el sentido de movimiento y procede a llamar a la

funcion que lleva a

// cabo el desplazamiento.

// Estados afectados: Resultado de la tarea. Posicion actual.

void movimiento (int accion)

{

if(accion==0)

return;

//Desplazamiento.

electroiman(0); //Contraer electroiman.

if(*info == 0)

return;

Ninterrupts=0;

accion = accion*3 - 1; // Determinacion de cantidad de interrupciones a

realizarse

if(giro==1)

derecha = 1;

else

Page 35: Carro de transferencia

reversa=1;

while (Ninterrupts<accion) // Bucle de movimiento, continuo control

sobre la cantidad de interuupciones que se llevan a cabo.

{

cutil=cutilmax;

set_pwm1_duty(cutil);

printf(lcd_putc,"\hPos actual: %d \n%s",*(info+2),donde);

}

frenado(); // Proceso de frenado y detencion.

if(DetPosicion()==0)

{

reubicar_en(*(info+2)); // Intento de

reubicacion.

if (*(info)==0)

return;

}

for (int j=0; j<3; j++)

{

electroiman(1);

if(*info==0)

calibrar(); // Intento de calibracion.

else

j = 5;

}

printf(lcd_putc,"\hElectroiman \nActivado ");

derecha=0;

reversa=0;

if (*info==0)

return;

*info=1; // Actualizacion del resultado de la

tarea.

return;

}

// SECUENCIA DE CARGA O DESCARGA

// Segun la posicion y la distancia a la que se encuentra realiza el proceso de

carga o de descarga.

// inicia la secuencias de procesos que realice dicha tarea.

// Estados afectados: Resultado de la tarea.

void SecCD (void)

{

int intento = 0;

set_adc_channel(1);

delay_ms(10);

while (intento<3)

{

intento++;

if (Test_electroiman == 1)

{

while(leer_pulsadores()!='S')

{

set_adc_channel(1);

delay_ms(20);

printf(lcd_putc,"\fDistancia \n%li

",read_adc_prom(10));

delay_ms(50);

}

set_adc_channel(1);

delay_ms(20);

if (read_adc_prom(10)<270) // Verificar los valores

de conversion y colocar adecuadamente.

{

if (*(info+2)==2)

{

printf(lcd_putc,"\fDescargando\nEstante en via

2");

Page 36: Carro de transferencia

Puerta1 = 1;

delay_ms(T_puerta);

descargar();

if(*info==0)

return;

delay_ms(T_puerta);

Puerta1 = 0;

}

else if (*(info+2)==5)

{

printf(lcd_putc,"\fDescargando\nEstante en via

5");

Puerta2 = 1;

delay_ms(T_puerta);

descargar();

if(*info==0)

return;

delay_ms(T_puerta);

Puerta2 = 0;

}

else if (*(info+2)==7)

{

printf(lcd_putc,"\fDescargando\nVagon en via 7");

Puerta3 = 1;

delay_ms(T_puerta);

descargar();

if(*info==0)

return;

delay_ms(T_puerta);

Puerta3 = 0;

}

return;

}

else if (read_adc_prom(10)>700) // Verificar los

valores de conversion y colocar adecuadamente.

{

printf(lcd_putc,"\fCargando\nEstante en via 2");

if (*(info+2)==1 || *(info+2)==3 || *(info+2)==4 ||

*(info+2)==6)

cargar();

if(*info==0)

return;

return;

}

else

{

*info = 0;

return;

}

}

else

{

*info = 0;

electroiman(1);

}

delay_ms(200);

}

*info = 0;

return;

}

// PROCESO DE DESCARGA

// Controla y acciona el brazo de descarga. Empuja el elemento una determinada

cantidad de veces y si el mismo

// no alcanza la distancia esperada arroja un error.

// Estados afectados: Resultado de la tarea.

Page 37: Carro de transferencia

void descargar (void)

{

int I=0;

int T_out = 0;

//Extension "controlada"

while(read_adc_prom(10)<700 && I<3 && T_out < 2*T_out_brazo)

{

T_out++;

set_adc_channel(1); // Lectura de distancia

delay_ms(115);

printf(lcd_putc,"\hExtendiendo ");

printf(lcd_putc,"\nDistancia: %li ",read_adc_prom(10));

if(sensor2==1)

{

ext_brazo = 1;

delay_ms(30);

enc_brazo = 1;

}

else

{

I++;

enc_brazo = 0;

delay_ms(500);

contraer();

if(*info==0)

return;

}

delay_ms(100);

}

//Contraer

contraer();

if(read_adc_prom(10)<700)

{*info=0;return;}

if(T_out>=2*T_out_brazo)

{*info=0;return;}

if(*info==0)

return;

if(I<4)

*info = 1;

else

*info = 0;

return;

}

// PROCESO DE CARGA

// Activa y controla el brazo de descarga. Retorna un error cuando intenta

repetitivamente cargar el elemento

// y no se produce un acercamiento del mismo.

// Estados afectados: Resultado de la tarea.

void cargar (void)

{

int T_out = 0;

int I=0;

//extender

set_adc_channel(1); // Lectura de distancia

delay_ms(20);

if(read_adc_prom(10)>270)

extender();

if(*info==0)

return;

//Contraccion "controlada"

while(read_adc_prom(10)>270 && I<3 && T_out < 2*T_out_brazo)

{

T_out++;

set_adc_channel(1); // Lectura de distancia

delay_ms(115);

Page 38: Carro de transferencia

printf(lcd_putc,"\hContraendo ");

printf(lcd_putc,"\nDistancia: %li ",read_adc_prom(10));

if(sensor1==0)

{

ext_brazo = 0;

delay_ms(30);

enc_brazo = 1;

}

else

{

I++;

enc_brazo = 0;

delay_ms(500);

extender();

if(*info==0)

return;

}

delay_ms(100);

}

contraer();

if(read_adc_prom(10)>270)

{*info=0;return;}

if(T_out>=2*T_out_brazo)

{*info=0;return;}

if(*info==0)

return;

if(I<4)

*info = 1;

return;

}

// Extender

// Activa y controla el brazo de descarga. Retorna un error cuando intenta

repetitivamente cargar el elemento

// y no se produce un acercamiento del mismo.

// Estados afectados: Resultado de la tarea.

void extender (void)

{

int T_out = 0;

enc_brazo = 0;

ext_brazo = 0;

if(sensor2==1)

{

printf(lcd_putc,"\fExtendiendo\nBrazo");

ext_brazo = 1;

delay_ms(30);

enc_brazo = 1;

while(sensor2==1 && T_out<T_out_brazo)

{

delay_ms(500);

T_out++;

}

enc_brazo = 0;

}

delay_ms(500);

if(T_out<T_out_brazo)

{*info=1;return;}

else

{*info=0;return;}

}

//Contraer

void contraer (void)

{

int T_out = 0;

int I=0;

Page 39: Carro de transferencia

enc_brazo = 0;

ext_brazo = 0;

if(sensor1==0)

{

printf(lcd_putc,"\fContraendo\nBrazo");

ext_brazo = 0;

delay_ms(30);

enc_brazo = 1;

while(sensor1==0 && T_out<T_out_brazo)

{

delay_ms(500);

T_out++;

}

enc_brazo = 0;

}

delay_ms(500);

if(T_out<T_out_brazo)

{*info=1;return;}

else

{*info=0;return;}

}

// DETERMINACION DE LA POSICION CON SENSOR DE DISTANCIA

// Determina la posicion en la que se encuentra el carro y compara con el dato que

se tiene en el

// vector de infrmacion.

// Estados afectados: Resultado de la tarea.

int DetPosicion (void)

{

int16 dist=0;

printf(lcd_putc,"\hDeterminando \nPosicion ");

delay_ms(500);

while(leer_pulsadores()!='S')

{

set_adc_channel(0);

delay_ms(20);

printf(lcd_putc,"\fDistancia \n%li

",read_adc_prom(10));

delay_ms(50);

}

for (int i=0; i<3; i++)

{

set_adc_channel(0);

delay_ms(20);

dist = read_adc_prom(10);

// El sensor entrega 4-20mA.

// La tension maxima soportada por el micro es 5V por lo tanto se utiliza una

resistencia de 250 Ohhm en serie.

if (dist<Set_pos2[0]+tol_pos)

return 0;

else if (dist < Set_pos2[1]+tol_pos && dist > Set_pos2[1]-tol_pos)

return 1;

else if (dist < Set_pos2[2]+tol_pos && dist > Set_pos2[2]-tol_pos)

return 2;

else if (dist < Set_pos2[3]+tol_pos && dist > Set_pos2[3]-tol_pos)

return 3;

else if (dist < Set_pos2[4]+tol_pos && dist > Set_pos2[4]-tol_pos)

return 4;

else if (dist < Set_pos2[5]+tol_pos && dist > Set_pos2[5]-tol_pos)

return 5;

else if (dist < Set_pos2[6]+tol_pos && dist > Set_pos2[6]-tol_pos)

return 6;

else if (dist < Set_pos2[7]+tol_pos && dist > Set_pos2[7]-tol_pos)

return 7;

Page 40: Carro de transferencia

else

return 0;

}

}

// REUBICACION

// Recupera la ubicacion del carro en caso de no poder realizar las tareas de carga

y descarga.

// Estados afectados: Resultado de la tarea. Alarma.

void reubicar_en (int en_pos)

{

int conta_cero=0;

int posiciones_temp[6];

Ninterrupts=0;

if(*(info+2)>4)

giro=1;

if(*(info+2)<=4)

giro=0;

if(giro==1)

derecha = 1;

else

reversa=1;

printf(lcd_putc,"\hReubicando... ");

for(int k=0;k<6;k++)

{

frenado();

posiciones_temp[k] = DetPosicion();

if(posiciones_temp[k]==0)

conta_cero++;

}

if(conta_cero==4)

{

if(giro==1)

giro = 0;

else

giro=1;

if(giro==1)

derecha = 1;

else

reversa=1;

if(posiciones_temp[5]!=0)

*(info+2)=posiciones_temp[5];

else if(posiciones_temp[4]!=0)

{

frenado();

if(posiciones_temp[4]==DetPosicion())

*(info+2)=posiciones_temp[4];

}

else if(posiciones_temp[3]!=0)

{

frenado();

if(posiciones_temp[3]==DetPosicion())

*(info+2)=posiciones_temp[3];

}

else

*info=0;

*info=1;

return;

}

else

*info=0;

return;

}

// ELECTROIMAN

// Funcion destinada a activar el seguro (electroiman) y controlar su estado.

Page 41: Carro de transferencia

// Con un estado alto de Test_electroian se asegura que el electroiman esta

extendido, de lo contrario el estado es bajo.

// Estados afectados: Resultado de la tarea.

void electroiman (int activ)

{

int i=0;

derecha = 0;

reversa = 0;

if(activ==1)

{

i=0;

printf(lcd_putc,"\hActivando \nElectroiman... ");

while (Test_electroiman==0 && i<5)

{

A_electroiman = 0;

delay_ms(500);

i++;

A_electroiman = 1;

delay_ms(1000);

}

}

else

{

i=0;

printf(lcd_putc,"\hDesactivando \nElectroiman... ");

while (Test_electroiman==1 && i<5)

{

A_electroiman = 1;

delay_ms(500);

i++;

A_electroiman = 0;

delay_ms(1000);

}

}

if(i==5)

*info = 0;

else

*info = 1;

return;

}

// CALIBRACION DE LA POSICION

// Esta funcion hace un reajuste para alinear correctamente el carro y electroiman

pueda ser activado.

// Estados afectados: Ninguno.

void calibrar (void)

{

cutil = cutilmax;

printf(lcd_putc,"\hCalibrando...... ");

A_electroiman = 0;

if(*(info+2)>4)

giro=1;

if(*(info+2)<=4)

giro=0;

set_pwm1_duty(cutil);

if(giro==1)

derecha = 1;

else

reversa=1;

delay_ms(1000);

cutil = 500;

set_pwm1_duty(cutil);

delay_ms(500);

cutil = 100;

set_pwm1_duty(cutil);

derecha=0;

Page 42: Carro de transferencia

reversa=0;

delay_ms(50);

giro = !giro;

delay_ms(50);

if(giro==1)

derecha = 1;

else

reversa=1;

cutil = 1;

Ninterrupts=0;

while(Ninterrupts==0);

set_pwm1_duty(cutil);

*info = 1;

return;

}

// FRENADO

// Desaceleracion lenta del carro

// Estados afectados: Ninguno.

void frenado (void)

{

cutil = cutilmax;

if(giro==1)

derecha = 1;

else

reversa=1;

Ninterrupts=2;

printf(lcd_putc,"\hFrenando en \n%s",donde);

while (Ninterrupts==2)

{

if(cutil>250)

cutil = cutil - 15;

else

cutil = *(info+8)*17;

set_pwm1_duty(cutil);

delay_ms(50);

}

giro=!giro;

delay_ms(*(info+7)); // Calibacion de inversion para frenado.

set_pwm1_duty(0);

Ninterrupts=0;

printf(lcd_putc,"\hParado en via de \n%s",donde);

delay_ms(1000);

derecha=0;

reversa=0;

return;

}

//Leer analogico con 10 muestras promediadas.

int16 read_adc_prom(int cant)

{

for(int f=0;f<cant;f++)

Lectura+=read_adc();

Lectura/=cant;

}

Page 43: Carro de transferencia

Anexo 4

Page 44: Carro de transferencia
Page 45: Carro de transferencia

Anexo 5

Page 46: Carro de transferencia
Page 47: Carro de transferencia

Anexo 6