Controlar desconexión ascensor

De Proyectos
Saltar a: navegación, buscar

Tareas

  • Un calendario para poder saber que dias ha de estar desconectado todo el dia o solo en horario laboral
  • Pantalla
    • Para poder configurar el dia en el que estamos y la hora
    • Poder ver el estado de si esta desconectado o no
  • Teclado
    • Introducir hora y dia
    • Poder hacer una desconexion manual (aunque esto puede hacerse desde el boton rojo que ya hay) - El circuito de desconexion no tiene que anular el del boton rojo
  • Antes de ponerlo hay que hacer pruebas de si es fiable estar siempre el arduino encendido, al ser esta una plataforma diseñada para pruebas
  • Mirar amperios que pasan por el boton rojo y voltios
  • Implementar funcion de subir el montacargas a la 4 planta
    • Mirar amperios que pasan por el boton y voltios
  • Bateria litio para supuesto cortan luz k siga funcionando. Aunque si cortan y vuelven a dar la pila del reloj mantiene hora i al dar otra vez el prog se ejecuta normalmnt
  • Almacenar calendario n tarjeta sd para poder ajustar facilmnt
  • Mirar posibilidad configurar fiestas especiales o todo cale dsd keypad
  • Modo conf calendario dsd keypad, introducir primero mes y lego dias festivos separados por puntos. Hanilitar tmb introduccion periodos consecutivos
  • Estudiar dias festivos para ver k siempre sean iguales
  • Al introducir dias festivos, quitar el anterior o dejar anteriores y quitar permitar solo seleccionados
  • Leer hora cada segundo o leer hora una vez al dia y k arduino cuente solo un dia
  • Politica d lectura de dia, cada cuanto leo el dia del mes? Podria contar el arduino 28 dias que es lo minimo que tiene el mes i luego preguntar cada 24 horas la fecha al reloj durante 4 dias (para llegar al maximo de 31 dias)
    • Pero no se si esto gasta mas (codigo y tiempo) que preguntar cada 24 horas el dia
  • Hacer el programa teniendo en cuenta que si se resetea empieza correctamnt
  • Cuando se introduzca la hora o un dia festivo tiene que salir un mensaje traduciendo los datos a entendibles y preguntando confirmacion
  • Se puede utilizar shift Register para ahorrar pines para el keypad?
  • Control tiempo max espera entrada datos. Para hacerlo leer milis antes del bucle y en el bucle controlar que si milos es superior a 2 min salga del bucle


Ejecución código

Proceso desconexión

  • Muestro hora y fecha
  • Proceso desconexion en marcha
    • Leo Hora
    • Leo Dia
    • Si dia y hora laborables entonces //Hora desde 7.30 hasta 17.50
      • Desactivo Stop
      • Desactivo Led
    • Sino si hora es igual a 17.50 y dias es laborable entonces //Empiezo proceso de desconexion
      • Espero puertas cerrar
      • Llamo planta 4
      • Espero ascensor llegue
      • Activo Stop
      • Activo Led
    • Sino //dias de fiesta o horas no laborables. Realmente este caso no se necesita porque de seri el rele de stop y el led estan activados
      • Activo rele Stop
      • Activo led

Proceso menu

  • Si aprieto * entro en menu
    • Dibujo menú
    • Espero opción valida (1,2,3,4 o #)
    • Si opcion es 1 entonces
      • Muestro configuración hora
      • Espero entrada de hora //hago las comprobaciones de si la hora entrada es correcta
      • Muestro configuracion dia
      • Espero entrada de dia //hago las comprobaciones de si el dia entrado es correcto
    • Sino Si opcion es 2 entonces
      • Muestro configuracion dia festivo
      • Espero entrada nuevo dia festivo //hago las comprobaciones de si dia festivo es correcto
      • Guardo nuevo dia en SD
    • Sino Si opcion es 3 entonces
      • Extraigo SD
    • Sino Si opcion es 4 entonces
      • Modo Demo


El proceso de desconexión tiene que estar funcionando siempre, aunque entre en el menú y me ponga a configurar cosas. El caso mas desfavorable es cuando estoy en el menú y la ejecución esta parada esperando una entrada de tecla. Incluso en este caso la ejecución de desconexión no debe pararse. El proceso de estar atento a la entrada de la tecla *, mientras se ejecuta el proceso de desconexión, lo tengo implementado pero no se si de forma optima o no.


Soluciones a interferencia entre de los procesos desconexion y menu

  • OPCION 01: A 10 o 20 min desconexión no poder entrar en menú. Si se entra la espera de datos sera max 2 min. Problema --> si voy viajando entre menús menos de dos min por cada uno puedo pasarme de la hora de desconexión
  • OPCION 02: Debería ser que si a las 17.50 no se ha podido iniciar lo intente cada 10 min. Tiene que haber una variable que guarde si la desconexión/conexión se ha realizado. Con esto juntamente que no se puede estar esperando una entrada mas de dos min me aseguro que el p desconexión se ejecute siempre
  • OPCION 03: Interrupciones: creo que si la interrupción se encarga de la desconexión, mirando cada x tiempo la hora y si llega la hora se ejecuta el p desconexión. El p menú estaria en el principal. Pero esto no se como hacerlo
  • OPCION 04: En el bucle principal pongo condición de entrar en menú que se apriete la tecla asterisco y que no sean 10 o 20 min antes de la hora de conex/descon. En los bucles de espera de datos hago lo mismo. Si son 10 o 20 min antes se sale del bucle. Haciendo que se cierren los procesos hasta llegar al principal que entonces ira directamente al proceso desconexion
  • OPCION 05: En cada bucle que espere entrada de tecla se llama al proceso desconexion. Con esto me aseguro que aunque este en espera a que el usuario introduzca un dato el proceso de desconexion se lleva a cabo. Hay que tener en cuenta de que el proceso de desconexión sea autónomo (no haga falta que se le envien variables), porque sino se convierte en un lio tener que llevar las variables hasta el bucle de espera para pasárselas al proceso desconexion.


Elementos

  • Para el reloj y calendario
    • DS1307
    • DS3231 (este lleva el cristal incorporado)
      • Conexion via i2c
      • Ocupa 2 pines
  • Rele para desconexion ascensor - ocupa 1 pin
  • Rele para llamar al piso 4 - ocupa 1 pin
  • Interruptor para desconexion general Arduino y que siga el funcionamiento normal del ascensor
  • LCD
    • DFR0091
      • Conexion via SPI - ocupa 3 pines
      • 128x64 Liquid Crystal
      • 4 lines and 12 English characters
    • DFR0063
      • Conexion i2c - ocupa 2 pines
      • 16x2
  • Keypad - ocupa 7 pines
  • Led para mostrar si esta desconectado el ascensor o no - ocupa 1 pin
  • SD para guardar dias festivos (SPI) - ocupa 4 pines


Uso Pines Arduino Uno

  • SPI (LCD y SD)- 9-13
  • I2C - A4 y A5
  • Keypad - 2-8
  • Reles - A0 y A1
  • Led - A2

Libres: A3


Uso Pines Arduino Leonardo

  • (LCD) I2C software - 5 - 7
  • (SD) SPI (MOSI, MISO, CLK) en ICSP + SS pin 4
  • (RTC)I2C - 2 y 3
  • Keypad - 8 - 10
  • Reles - 11 -13
  • Led - A0

Libres: A1 A2 A3 A4 A5

Si utilizara ci para convertir todos los componenetes (excepto reles y led) a i2c me quedaria la siguiente configuración:

  • (LCD, RTC, Keypad) I2C - 2 y 3
  • (SD) SPI (MOSI, MISO, SCLK en ICSP) SS - 4
  • Reles - 5 6 7
  • Led - 8

Libres: A0-A5 9-13


Programacion

  • Módulo Reloj/Calendario
    • Funcion lectura datos reloj
    • Funcion escritura datos reloj (puesta en hora del reloj)
  • Módulo SD-Calendario
    • Escritura en el fichero los dias festivos
    • Lectura del fichero los dias festivos
    • Comprobar que detecta bien la SD
  • Módulo Mostrar datos en Pantalla
    • Menú
      • Configurar reloj
      • Configurar dias festivos
      • Verificar si lee correctamente SD
      • Desconectar manualmente el ascensor a traves de una orden (no se si esto es necesario)
    • Hora y dia
    • Estado desconexion ascensor
  • Desconexión ascensor
  • Llamada planta 4


Orden de programación de los diferentes módulos

  • Programar proceso de desconexión integramente. Que sea funcional
    • Módulo de lectura de RTC
    • Módulo de lectura de SD
    • Relés
    • Sensores
    • Led
    • Módulo de mostrar en pantalla hora y fecha
  • Programar proceso menú
    • Módulo mostrar menú
    • Módulo submenus
      • Configurar Hora y Fecha
      • Configurar Calendario
      • Extraer SD


Entender los Componentes

  • RTC DS3231
    • Funciona con i2c. Hay una libreria en arduino (wire.h) que utilizamos para poder comunicarnos con dispositivos via i2c.
    • El DS3231 (a partir de ahora RTC) tiene unos registros. Cada registro contiene información que se puede leer o escribir. Por ejemplo en la direccion 00 estan almacenados los segundos, ...
    • El RTC trabaja con BCD
    • Objetivo 1: poder leer y escribir los registros del RTC
    • Objetivo 2: entender todas las posibilidades que tiene el RTC
    • Objetivo 3(no probable): entender como funciona el protocolo i2c y poder implementarlo yo
  • LCD12864 (LCD 128x64)
    • Funciona por SPI. Incluye libreria en DFRobot
    • ST7920 es el controlador de este lcd.
    • QC12864 v3.0 creo que es el modelo del lcd.
    • LCD12864 no se que es
    • Tiene 8192 carácteres de 16x16 guardados en la CGROM y 126 carácteres alfanuméricos de 8x16.
    • Los códigos de los caracteres estan escritos en la DDRAM y las fuentes conrrespondientes estan mapeadas desde la CGROM o la HCGROM hasta los drivers del display-->Que coño significa esto?¿?¿
    • Hay una libreria que parece estar bien programada para controlar este lcd. El problema es que esta programada para conexón en paralelo, no en spi


RTC DS3231

  • La libreria Wire.h
    • Tiene estas funciones: begin(), requestFrom(), beginTransmission(), endTransmission(), write(), available(), read(), onReceive(), onRequest()
    • De momento no entiendo muy bien como funciona la funcion Wire.write()
      • Tengo estos dos ejemplos:
  Wire.beginTransmission(0x68); // address DS3231
  Wire.write(0x0E); // select register
  Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
  Wire.endTransmission();
  Wire.beginTransmission(0x68); // 0x68 is DS3231 device address
  Wire.write(0); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(0x68, 3);

  while(Wire.available())
  { 
    int seconds = Wire.read(); // get seconds
    int minutes = Wire.read(); // get minutes
    int hours = Wire.read();   // get hours


En el primer ejemplo el beginTransmission seleciona el RTC. Luego seleccionar el registro a escribir con la funcion write. Luego envia unos bits con la misma funcion write y al final acaba la transmision con endTransmission.

En el segundo ejemplo empieza igual, selecciona el registro 0, acaba la transmisión y luego utiliza la función requestFrom para pedir tres direcciones. Que luego veo que las lee con Wire.read().


Entonces yo me pregunto:

  • Como funciona write si se esta usando de dos formas, una es al seleccionar el registro a escribir (o leer) y la otra es enviando bits para escribirlos.-->Respuesta: la función write envia los datos, no significa que escriba datos. Por lo que parece el primer write tiene que enviar el id del dipositivo y los demas writes envian datos a ese dispositvio. En el primer ejemplo se seleciona el registro de configuracion del RTC y luego se le envian los datos de como se quiere configurar ese registro. Por tanto, en los registros de los segundos, minutos, horas, ..., con la funcion write escribo en esos registros y con la funcion read leo de esos registros.
  • Que hace la función requestFrom.--> Respuesta: Used by the master to request bytes from a slave device. The bytes may then be retrieved with the available() and read() functions.
  • Como se lee esta notación: 0b00011100-->Respuesta: Por lo que parece 0b es la manera de decirle a arduino que vamos a escribir un numero en binario. En una página pone que el compilador de arduino no lo admite, pero teniendo en cuenta de que en el ejemplo primero si que se compila correctamente, voy a suponer que esa página debe de referirse a alguna version antigua a la 1.0.1. También en visto la notacion B seguido de binarios para referirse a un numero binario, pero eso sale en los Integer Constants de la página de referencia de arduino. No se si se puede aplicar en cualquier parte del sketch.
    • Podria comprobar esto enviando la hora en binario al RTC y luego al leerla si se ha escrito bien significa que es la notacion en binario.-->Comprobado, es cierto
  • Para escribir datos en los registros:
Wire.begin(); //Empieza transmisión
Wire.beginTransmission(0x68); //Selecciono el RTC
Wire.write(0x01); //Seleciono la dirección del registro a modificar. En este caso los minutos
Wire.write(0b000110110); //Envio los datos en modo binario pero en BCD. En este caso (de MSB a LSB), el primer es 0 pq lo dice el datasheet, 011 equivale a 3 y 0110 equivale a 6. Estoy transmitiendo 36 minutos
Wire.endTransmission(); //Finaliza transmisión
  • Para leer datos de los registros:
Wire.begin(); //Empieza transmisión
Wire.beginTransmission(0x68); //Selecciono el RTC
Wire.write(0x01); //Selecciono la direccion del registro a leer
Wire.endTransmission(); //Cierro la conexión. Hace falta decir que esta conexión solo se establece para seleccionar el registro que posteriormente leeré, al menos esa es la conclusión que yo he sacado.
Wire.requestFrom(0x68, 1); //Con esta función le estamos pidiendo al RTC que nos envie un byte de información, como previamente le dijimos que queriamos el registro 0x01, nos enviará los minutos.
int minutes = Wire.read(); //Leemos los datos que nos envia el RTC y los guardamos en una variable
  • Despues de leerme para lo que sirven los registros solo encuentro necesario en la dirección 0x0F (Control/Status) el bit OSF. Según el datasheet si está a 1 significa que el oscilador está parado y entonces el tiempo que nos da es inexacto. Dice que esto pasa por una serie de razones, de las cuales una es al conectar por primera vez el VCC. Antes de poder utilizarlo deberia ponerlo a 0, para asegurarme de utilizar las capacidades de este RTC. Encuentro extraño que se ponga a 1 al conectarse, porque entonces porque quiero un RTC con oscilador incorporado en que sino configuro desde el principio, este oscilador está parado? En la web de macatech (el creador del ChronoDot esto no sale explicado, pero yo por si acaso lo pondré en 0.
  • También hay que tener en cuenta el EOSC del Control del registro. Según leo cuando esta a 0 el oscilador se enciende, pero si esta a 1 el oscilador se para cuando entra en modo bateria. Tengo que asegurarme de que siempre este a 0
  • Necesito que Arduino sincronize el tiempo con el RTC para este proyecto? Por lo que puedo leer en este post, Arduino no tiene un calculo preciso del tiempo y necesita ir sincronizandose con el RTC para poder tenerlo. También dice que la funcion millis() depende de ese "tiempo poco preciso" que tiene Arduino, y como yo utilizo en algunos sitios esa funcion, significa que tengo que sincronizar la "hora" de Arduino con la del RTC?
    • Para hacerlo dicen que hay dos funciones:
      • setSyncProvider(): Esta función se usa para definir a que función llamar cuando se necesite sincronizar la hora
      • setSyncInterval(): Esta función define cada cuento se sincroniza la "hora" de Arduino con la del RTC


LCD12864

  • Que es u8glib. He llegado aqui porque un tipo dice que puede escribir mas lineas en este lcd porque hace la letra más pequeña.
  • Como se controla este lcd? es decir, tenemos el chip ST7920 que para que me sirve saber como funciona? Si entiendo el funcionamiento del ST7920 puedo manipular el lcd a mi antojo? o no es necesario.
  • Aqui tengo dos problemas:
    • Como enviar los datos por SPI (se que la SD funciona tambien por SPI por tanto cuando tenga la pantalla puedo sacar conclusiones con la SD)
    • Como escribir en la pantalla
      • Presentar los datos para que la pantalla los entienda
      • Hacer animaciones (esto es secundario)
      • Como escojer donde quiero escribir o donde quiero borrar


Funciones a crear:

  • Inicializar LCD
  • Funcion para escribir caracteres alphanumericos
  • Funcion para desplazar el cursor
  • Funcion para hacer scroll (vert y hor)


He podido crear una libreria propia que funciona como la LiquidCrystal pero para este lcd. El problema es que solo puedo escribir 4 lineas
Hay un proyecto u8glib, que me permite escribir 8 lineas, el problema es que las fuentes ocupan mucho, unos 5 kB, y solo el menu me ocuparia unos 8kB de los 32 kB disponibles.
Entonces veo dos opciones:

  • Me apaño con las 4 lineas
  • Pongo una epprom adicional para guardar las fuentes y modificar la libreria u8glib para que busque las fuentes ahi (cosa qu eno se ni por donde empezar)


El datasheet me parece bastante confuso, de momento no se si entiendo todo, pero me gustaria hacer pruebas para poder entender todas las posibilidades que tiene este lcd y documentarlo todo.

Documentación

http://tronixstuff.wordpress.com/2011/05/13/tutorial-arduino-and-the-spi-bus/ http://www.instructables.com/id/Using-the-sparkfun-12-Button-keypad-with-the-ardu/?ALLSTEPS ---- Wiring keypad correcto para ejemplos arduino Keypad coocking hacks:

1 2 3 -- 2
4 5 6 -- 7
7 8 9 -- 6
* 0 # -- 4
| | |
3 1 5