/* ascenseur.c */ /* n.avr.carte_capteurs - AVR Carte_capteur Module. {{{ * * Copyright (C) 2005 Dalmais Romain * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Contact : * Web: http://perso.efrei.fr/~dalmais * Email: * }}} */ #include "ascenseur.h" #include "avr/io.h" /* Pin des capteurs. */ #define CAPTEUR_BAS 0 #define CAPTEUR_MILIEU 1 #define CAPTEUR_HAUT 2 uint8_t ascenseur_vitesse_voulue; uint8_t ascenseur_vitesse; uint8_t ascenseur_min_monte = 0x20; uint8_t ascenseur_max_monte = 0x05; uint8_t ascenseur_accel_monte = 1; uint8_t ascenseur_min_descend = 0x10; uint8_t ascenseur_max_descend = 0x01; uint8_t ascenseur_accel_descend = 1; uint8_t ascenseur_max; uint8_t ascenseur_min; uint8_t ascenseur_accel; uint8_t ascenseur_state = WAIT; uint8_t asc_ordre; uint8_t asc_message; #define TC_STOP 0x00 #define TC_GO 0x1f /* mode CTC | OC2 | prescaler = 128. */ /* +AutoDec */ /* -AutoDec */ static void asc_haut(uint8_t valeur); static void asc_bas(uint8_t valeur); static void asc_stable(void); static void asc_libre(void); static uint8_t capteur_bas(); static uint8_t capteur_haut(); static uint8_t capteur_milieu(); static void asc_libre(void); static void ascenseur_update_vitesse (void); void ascenseur_init () { TCCR2 = TC_STOP; ascenseur_state = WAIT; asc_libre(); } void ascenseur_update () { switch (ascenseur_state) { case CMD_Mgrande: // monter à vive allure ascenseur_update_vitesse (); asc_haut (ascenseur_vitesse); asc_message = 255; asc_ordre = 0; // annulle l'éventuelle ordre utilisateur if (capteur_bas()) ascenseur_state = CMD_Mgrande; else ascenseur_state = CMD_Mgrande_c; break; case CMD_Mgrande_c: asc_ordre = 0; // annulle l'éventuelle ordre utilisateur ascenseur_update_vitesse (); asc_haut (ascenseur_vitesse); asc_message = 255; if (capteur_bas()) ascenseur_state = ERR; else if (capteur_haut()) ascenseur_state = CMD_Mpetite; else ascenseur_state = CMD_Mgrande; break; case CMD_Mpetite: // monter en réduisant la vitesse asc_ordre = 0; // annulle l'éventuelle ordre utilisateur ascenseur_vitesse_voulue = ascenseur_min; ascenseur_update_vitesse (); asc_haut (ascenseur_vitesse); asc_message = 255; if (capteur_bas()) ascenseur_state = ERR; else if (capteur_haut()) ascenseur_state = CMD_Mpetite; else ascenseur_state = TENIR; break; case TENIR: // maintenir le mobile en haut asc_stable(); if (asc_message != 0) asc_message = 1; if (capteur_bas()) ascenseur_state = ERR; else if (asc_ordre == 0x02) { ascenseur_state = CMD_D; asc_ordre = 0; } else ascenseur_state = TENIR; break; case CMD_D_c: asc_ordre = 0; // annulle l'éventeuelle ordre utilisateur ascenseur_vitesse_voulue = ascenseur_max; ascenseur_update_vitesse (); asc_bas (ascenseur_vitesse); asc_message = 255; if (capteur_haut()) ascenseur_state = CMD_D_c; else ascenseur_state = CMD_D; break; case CMD_D: // descente du mobile asc_ordre = 0; // annulle l'éventuelle ordre utilisateur ascenseur_vitesse_voulue = ascenseur_max; ascenseur_update_vitesse (); asc_bas (ascenseur_vitesse); asc_message = 255; if (capteur_bas()) ascenseur_state = ERR; else if (!capteur_milieu()) ascenseur_state = CMD_D; else ascenseur_state = WAIT; break; case WAIT: // attente mobile normalement en bas asc_libre(); if (asc_message != 0) asc_message = 3; if (capteur_bas() && (asc_ordre ==0x01 )) { ascenseur_state = CMD_Mgrande; asc_ordre = 0; } else ascenseur_state = WAIT; break; case ERR: // etat d'erreur if (asc_message != 0) asc_message = 2; asc_libre(); if (capteur_bas() && (asc_ordre == 0x01)) { ascenseur_state = CMD_Mgrande; asc_ordre = 0; } else ascenseur_state = ERR; } } static void ascenseur_update_vitesse (void) { if (ascenseur_vitesse < ascenseur_vitesse_voulue) { ascenseur_vitesse += ascenseur_vitesse_voulue; if (ascenseur_vitesse > ascenseur_vitesse_voulue) ascenseur_vitesse = ascenseur_vitesse_voulue; } else if (ascenseur_vitesse > ascenseur_vitesse_voulue) { ascenseur_vitesse -= ascenseur_vitesse_voulue; if (ascenseur_vitesse < ascenseur_vitesse_voulue) ascenseur_vitesse = ascenseur_vitesse_voulue; } } static void asc_haut(uint8_t valeur) { PORTB |= _BV(0); // sens TCCR2 = TC_GO; OCR2 = valeur; PORTD |= _BV(6); // on enable } static void asc_bas(uint8_t valeur) { PORTB &= ~_BV(0); TCCR2 = TC_GO; OCR2 = valeur; PORTD |= _BV(6); } static void asc_stable(void) { TCCR2 = TC_STOP; PORTD |= _BV(6); } static void asc_libre(void) { TCCR2 = TC_STOP; PORTD &= ~_BV(6); } static uint8_t capteur_bas() { return !(PINA & _BV(CAPTEUR_BAS)); } static uint8_t capteur_haut() { return !(PINA & _BV(CAPTEUR_HAUT)); } static uint8_t capteur_milieu() { return !(PINA & _BV(CAPTEUR_MILIEU)); }