Wiselib
|
00001 /*************************************************************************** 00002 ** This file is part of the generic algorithm library Wiselib. ** 00003 ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project. ** 00004 ** ** 00005 ** The Wiselib is free software: you can redistribute it and/or modify ** 00006 ** it under the terms of the GNU Lesser General Public License as ** 00007 ** published by the Free Software Foundation, either version 3 of the ** 00008 ** License, or (at your option) any later version. ** 00009 ** ** 00010 ** The Wiselib is distributed in the hope that it will be useful, ** 00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** 00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** 00013 ** GNU Lesser General Public License for more details. ** 00014 ** ** 00015 ** You should have received a copy of the GNU Lesser General Public ** 00016 ** License along with the Wiselib. ** 00017 ** If not, see <http://www.gnu.org/licenses/>. ** 00018 ***************************************************************************/ 00019 00020 #ifndef _ISENSE_PIR_SENSOR_H 00021 #define _ISENSE_PIR_SENSOR_H 00022 00023 #include "config_testing.h" 00024 #include "external_interface/isense/isense_types.h" 00025 #include "util/base_classes/state_callback_base.h" 00026 #include <isense/os.h> 00027 #include <isense/modules/security_module/pir_sensor.h> 00028 #include <isense/timeout_handler.h> 00029 #include <isense/modules/core_module/core_module.h> 00030 #include <isense/time.h> 00031 00032 #define SECOND 1000 00033 #define MINUTE 60*SECOND 00034 00035 #define MIN_T 5*SECOND 00036 #define MAX_T 20*SECOND 00037 00038 00039 namespace wiselib 00040 { 00041 template<typename OsModel_P,int PIR_INTERVAL = SECOND > 00042 class iSensePirSensor 00043 : public isense::TimeoutHandler, 00044 public isense::SensorHandler 00045 { 00046 public: 00047 typedef OsModel_P OsModel; 00048 00049 typedef iSensePirSensor<OsModel> self_type; 00050 typedef self_type* self_pointer_t; 00051 00052 typedef bool value_t; 00053 // -------------------------------------------------------------------- 00054 enum ErrorCodes 00055 { 00056 SUCCESS = OsModel::SUCCESS, 00057 ERR_UNSPEC = OsModel::ERR_UNSPEC 00058 }; 00059 // -------------------------------------------------------------------- 00060 enum States 00061 { 00062 READY = OsModel::READY, 00063 NO_VALUE = OsModel::NO_VALUE, 00064 INACTIVE = OsModel::INACTIVE 00065 }; 00066 // -------------------------------------------------------------------- 00067 iSensePirSensor( isense::Os& os ) 00068 : os_ ( os ), 00069 state_ ( INACTIVE ) 00070 { 00071 os_.debug("BOOT OCCUPATION APP"); 00072 00073 // os().allow_sleep(false); 00074 pir_ = new isense::PirSensor(os); 00075 cm_ = new isense::CoreModule(os_); 00076 if (cm_ == NULL) 00077 os_.fatal("Could not allocate CoreModule"); 00078 00079 change_to_free1(); 00080 lastTime = os_.time(); 00081 pir_->register_sensor_handler(this); 00082 pir_->set_pir_sensor_int_interval(PIR_INTERVAL); 00083 pir_->enable(); 00084 00085 os_.add_timeout_in(MIN_T, this, NULL); 00086 state_ = READY; 00087 } 00088 // -------------------------------------------------------------------- 00089 int state() 00090 { 00091 return state_; 00092 } 00093 // -------------------------------------------------------------------- 00094 value_t operator()() 00095 { 00096 return actualState == OCCUPIED; 00097 } 00098 //---------------------------------------------------------------------------- 00099 00100 void timeout(void* userdata) 00101 { 00102 state_machine(false); 00103 os_.add_timeout_in(MIN_T, this, NULL); 00104 } 00105 00106 //---------------------------------------------------------------------------- 00107 00108 void handle_sensor() 00109 { 00110 os_.debug("PIR detected something..."); 00111 lastTime = os_.time(); 00112 state_machine(true); 00113 } 00114 // -------------------------------------------------------------------- 00115 00116 00117 private: 00118 // -------------------------------------------------------------------- 00119 isense::Os& os() 00120 { return os_; } 00121 // -------------------------------------------------------------------- 00122 isense::Os& os_; 00123 isense::CoreModule* cm_; 00124 isense::PirSensor* pir_; 00125 00126 unsigned int actualState; 00127 isense::Time firstTime,lastTime; 00128 00129 States state_; 00130 00131 enum state 00132 { 00133 FREE1 = 0x00, 00134 FREE2 = 0x01, 00135 OCCUPIED = 0x02, 00136 UNKNOWN = 0x03 00137 }; 00138 00139 void state_machine(bool pir) 00140 { 00141 isense::Time diffTime = (os_.time()-lastTime); 00142 isense::Time firstDiffTime = (os_.time()-firstTime); 00143 switch(actualState) 00144 { 00145 case FREE1: 00146 if(pir) 00147 { 00148 change_to_free2(); 00149 } 00150 break; 00151 case FREE2: 00152 if(firstDiffTime>MAX_T) 00153 { 00154 change_to_free1(); 00155 } 00156 else if(pir && firstDiffTime>=MIN_T && firstDiffTime<=MAX_T) 00157 { 00158 change_to_occupied(); 00159 } 00160 else if(diffTime>MAX_T || firstDiffTime>MAX_T) 00161 { 00162 change_to_unknown(); 00163 } 00164 break; 00165 case OCCUPIED: 00166 if(diffTime>MAX_T) 00167 { 00168 change_to_free1(); 00169 } 00170 // else if(diffTime>MAX_T || firstDiffTime>MAX_T) 00171 // { 00172 // change_to_unknown(); 00173 // } 00174 break; 00175 case UNKNOWN: 00176 if(pir) 00177 { 00178 change_to_free2(); 00179 } 00180 else 00181 { 00182 change_to_free1(); 00183 } 00184 break; 00185 default: 00186 break; 00187 } 00188 } 00189 00190 void change_to_free1() 00191 { 00192 os_.debug("Free 1"); 00193 cm_->led_off(); 00194 actualState = FREE1; 00195 } 00196 00197 void change_to_free2() 00198 { 00199 os_.debug("Free 2"); 00200 cm_->led_off(); 00201 firstTime=lastTime; 00202 actualState = FREE2; 00203 } 00204 00205 void change_to_occupied() 00206 { 00207 os_.debug("Occupied"); 00208 cm_->led_on(); 00209 actualState = OCCUPIED; 00210 } 00211 00212 void change_to_unknown() 00213 { 00214 os_.debug("Unknown"); 00215 cm_->led_off(); 00216 actualState = UNKNOWN; 00217 } 00218 00219 }; 00220 } 00221 00222 #endif /* _ISENSE_PIR_SENSOR_H */ 00223