/*! \file ProximitySensor.H c++/ProximitySensor.H \brief C++ Proximity Sensor Class Interface \author Zhengrong.Zang@gmail.com \date 2013.10.01 Defines interface to Light sensor as proximity sensor */ // The contents of this file are subject to the Mozilla Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License // at http://www.mozilla.org/MPL/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See // the License for the specific language governing rights and // limitations under the License. // #ifndef _ProximitySensor_H_ #define _ProximitySensor_H_ #include #include #include #include #include #include #include #define PRXTHRESSHOLD 0x30 // difflight value #define TRANSMITTING 1 #define IDLE 0 extern volatile unsigned int proximity_counter; LightSensor *lightSensor; volatile unsigned int proximity_counter; // Reflection Counter (max 0x0a) volatile int clock_phase; // Indicator of Transmitter (TRANSMITTING | IDLE) volatile int detecting; // Detection Indicator tid_t Transmitter = 0, Counter = 0; int transmitter(int argc, char **argv){ while (!shutdown_requested()){ S_SR &= ~(SSR_TRANS_EMPTY | SSR_TRANS_END); // clean up Flags S_CR |= SCR_TRANSMIT; // enable Transmitter S_TDR = 0x00; // transmit as many lightpulses as possible clock_phase = TRANSMITTING; // Indicate transmitting // msleep(3); // wait a little while msleep(20); // wait a little while clock_phase = IDLE; // Indicate Idle msleep(40); // and wait again // msleep(6); // and wait again } return 0; } int count_reflections(int argc, char **argv){ int this_light = 0, last_light = 0; this_light = lightSensor->getRaw() >> 7; while (!shutdown_requested()){ proximity_counter = 0; // we have to wait until there is a transmission while (clock_phase == IDLE) {} while (clock_phase == TRANSMITTING){ detecting = 1; last_light = this_light; this_light = lightSensor->getRaw() >> 7; if (abs(last_light - this_light) > PRXTHRESSHOLD){ proximity_counter++; } } detecting = 0; } return 0; } int init_proximity(LightSensor *sensor){ lightSensor = sensor; // Set IR transmitter to longrange lnp_logical_range(1); // Check if there is a Transmitter Process running if (Transmitter != 0){ kill(Transmitter); Transmitter = 0; } // Start Transmitter Process Transmitter = execi(&transmitter, 0, 0, PRIO_NORMAL, DEFAULT_STACK_SIZE); // fork a new Process if (!Transmitter){ return 1; } // Check if there is a Counter Process running if (Counter != 0){ kill(Counter); Counter = 0; } // Start Counter Process Counter = execi(&count_reflections, 0, 0, PRIO_NORMAL, DEFAULT_STACK_SIZE); // and the second one if (!Counter){ kill(Transmitter); return 1; } return 0; } wakeup_t proximity_close(wakeup_t data) { return proximity_counter >= data && remote_key == 0; } wakeup_t proximity_far(wakeup_t data) { return proximity_counter == 0; } class ProximitySensor { private: Motor *motor; public: ProximitySensor() { } ProximitySensor(Motor *motor) { this->motor = motor; } void run() { while (!shutdown_requested()) { cputs("check"); wait_event(&proximity_close, 1); cputs("found"); Sound::beeps(); } } }; #endif // _ProximitySensor_H_